How to add/delete element in Flat array in C - arrays

I have a structure inside which char array and int value is maintained. I want to treat this char array as a flat array to store the list of strings and the offset will track the starting position where the string is added in the array.
Structure is shown below:
struct A
{
char element[256];
int offset;
}
Also, I want to delete the strings after performing some operation if found.
Please let me know if this feasible. If yes then how?

Yes, append to a.element[a.offset].
To delete, set a.element[0] to the null byte. C strings end at a null byte.
#include <stdio.h>
#include <string.h>
typedef struct
{
char element[256];
int offset;
} A;
void A_append(A* a, const char *str) {
// Concatenate on the end of element.
strcat(&a->element[a->offset], str);
// Increment the offset to the new end.
a->offset += strlen(str);
}
void A_delete(A* a) {
a->element[0] = '\0';
a->offset = 0;
}
int main() {
A a = { .element = "" };
a.offset = 0;
char string1[] = "one";
A_append(&a, string1);
char string2[] = "two";
A_append(&a, string2);
puts(a.element);
A_delete(&a);
puts(a.element);
}
You can also store a pointer to the end of element. It's the same thing, just more direct.
#include <stdio.h>
#include <string.h>
typedef struct
{
char element[256];
char *end;
} A;
void A_append(A* a, const char *str) {
// Concatenate nto the end of element.
strcat(a->end, str);
// Increment the pointer to the new end.
a->end += strlen(str);
}
void A_delete(A* a) {
a->element[0] = '\0';
a->end = a->element;
}
int main() {
A a = { .element = "" };
a.end = a.element;
char string1[] = "one";
A_append(&a, string1);
char string2[] = "two";
A_append(&a, string2);
puts(a.element);
A_delete(&a);
puts(a.element);
}
Finally, if you want to store a list of strings, not concatenate them, consider storing them as pointers.

Since all we have to go on is the question if it's feasible - and the answer is yes. Here's a way showing that it is:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct A A;
struct A {
char element[256];
int offset;
};
A *A_create() {
A *a = malloc(sizeof *a);
a->offset = 0;
return a;
}
void A_destroy(A *a) {
free(a);
}
// return false if the string doesn't fit
// true if it's successfully added
bool A_add_string(A *a, const char *str) {
size_t len = strlen(str);
if(a->offset + len >= sizeof a->element) return false;
memcpy(a->element + a->offset, str, len + 1);
a->offset += len + 1;
return true;
}
You can now create an A, add \0 terminated strings to it and finally destroy it:
A *a = A_create();
A_add_string(a, "Hello");
A_add_string(a, "world");
A_destroy(a);

Related

Copy a string to another string

I am following this algorithm that will copy one string to another string:
[S is a source string and T is a target string]
1. Set I = 0
2. Repeat step 3 while S[I] ≠ Null do
3. T[I] = S[I]
4. I = I + 1
[End of loop]
5. Set T[I] = Null
6. Return
I have attempted it but it instead removes the first n characters from source string relative to length of target string. For example:
#include <stdio.h>
#include <stdlib.h>
char const* stringCopy(char* T, char const* S){
while(*S){
*T++ = *S++;
}
//*T = 0;
return T;
}
int main(void){
char sentence[100] = "some sentence";
char* again = "another";
printf("%s", stringCopy(sentence, again));
return EXIT_SUCCESS;
}
You return the incremented original pointer T. Make a copy of T for the copy loop and return the original pointer.
#include <stdio.h>
#include <stdlib.h>
char const* stringCopy(char* T, char const* S){
char *ptr = T;
while(*ptr++ = *S++);
return T;
}
int main(void){
char sentence[100] = "some sentence";
char* again = "another";
printf("%s", stringCopy(sentence, again));
return EXIT_SUCCESS;
}

Attempting to make a Integer to Binary Converter in C, however it just prints random strings

I'm learning C at the moment and was making a Denary to Binary converter in C, and have come across this problem I just can't fix
// Includes
#include <stdio.h>
#include <math.h>
typedef enum {false,true} bool;
// intToBinary Function
char* intToBinary(int d)
{
bool not0 = true;
char* outputstr = "";
while(not0 == true)
{
int d = floor(d/2);
int rem = d % 2;
char num = rem;
outputstr += (char)num;
if(d==0)
{
printf("%s\n",outputstr);
return outputstr;
}
}
}
// Main Function
int main()
{
int inp;
printf("Enter A Number To Be Converted\n");
scanf("%d", &inp);
char* out = (char*)intToBinary(inp);
printf(out);
return 0;
}
I'm not sure why, but the only outputs I get are:
r To Be Converted
&
r To Be Converted(It repeats itself)
i'm compiling using msys on Windows 10
if you know what i've done wrong, could you tell me.
Thanks
char* outputstr = "";
You should not modify this string at all. It resides in implementation defined read only region. Modifying it causes Undefined Behavior.
You need a char array not a string literal.
Good Read:
What is the difference between char a[] = "string"; and char *p = "string";
Try this:
// Includes
#include <stdio.h>
#include <math.h>
typedef enum {false,true} bool;
char * append(char * string1, char * string2)
{
char * string3 = (char *) malloc(1 + strlen(string1)+strlen(string2) );
strcpy(string3, string1);
strcat(string3, string2);
return string3;
}
// intToBinary Function
char* intToBinary(int d)
{
bool not0 = true;
char* outputstr = "";
while(not0 == true)
{
d = d/2;
int rem = d % 2;
char num = (char)(rem+48);
char *s = &num;
outputstr = append(outputstr, s);
if(d==0)
{
printf("%s\n",outputstr);
return outputstr;
}
}
}

C: Take parts from a string without a delimiter (using strstr)

I have a string, for example: "Error_*_code_break_*_505_*_7.8"
I need to split the string with a loop by the delimiter "_*_" using the strstr function and input all parts into a new array, let's call it -
char *elements[4] = {"Error", "code_break", "505", "7.8"}
but strstr only gives me a pointer to a char, any help?
Note: the second string "code_break" should still contain "_", or in any other case.
This will get you half-way there. This program prints the split pieces of the string to the standard output; it does not make an array, but maybe you can add that yourself.
#include <stdio.h>
#include <string.h>
#include <malloc.h>
void split(const char * str, const char * delimiter)
{
char * writable_str = strdup(str);
if (writable_str == NULL) { return; }
char * remaining = writable_str;
while (1)
{
char * ending = strstr(remaining, delimiter);
if (ending != NULL) { *ending = 0; }
printf("%s\n", remaining);
if (ending == NULL) { break; }
remaining = ending + strlen(delimiter);
}
free(writable_str);
}
int main(void) {
const char * str = "Error_*_code_break_*_505_*_7.8";
const char * delimiter = "_*_";
split(str, delimiter);
return 0;
}
Here is a function that splits a string into an array. You have to pass the size of the array so that the function won't overfill it. It returns the number of things it put into the array. What it puts into the array is a pointer into the string that was passed. It modifies the string by inserting null characters to end the pieces - just like strtok does.
#include<string.h>
#include<stdio.h>
int split(char *string, char *delimiter, char* array[], int size)
{
int count=0;
char *current=string;
char *next;
while(current && *current!='\0')
{
next=strstr(current,delimiter);
if(!next)break;
*next='\0';
if(count<size) array[count++]=current;
current=next+strlen(delimiter);
}
if(count<size) array[count++]=current;
return count;
}
int main()
{
char string[100]="Error_*_code_break_*_505_*_7.8";
char *array[10];
int size=split(string,"_*_",array,10);
for(int i=0;i<size;i++) puts(array[i]);
return size;
}

Unable to store string in a struct

This code is a part of a bigger program. I want to create an array of structs. The struct contains two data types: char and char*, each of which gets an input from the user. I'm a rookie and not able to find my way through this. Please help.
Error generated: Segmentation Fault 11.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char ch;
char str[20];
}typ;
typ* add(char* str, char ch);
int main(int argc, char const *argv[]){
typ* arr;
arr = (typ*)malloc(sizeof(typ));
char* name;
name = (char*)malloc(10);
*(name + 0)= 'c';
*(name + 1)= 'a';
*(name + 2)= 'p';
*(name + 3)= '\0';
char c = 'k';
arr = add(name, c);
printf("%c\n", arr->ch );
printf("%s\n", arr->str );
return 0;
}
typ* add(char* str, char ch){
typ tempo;
strcpy(str, tempo.str);
printf("%s\n", str);
tempo.ch = ch;
typ* temp;
*temp = tempo;
return temp;
}
You used arr for the allocated memory, but then you assign it to add's return value, the memory got lost at this point, you have a memory leak.
In the add function, you return a pointer to a variable with automatic storage, which does not exists after the function returns. That's why you are getting a segfault.
So I would allocate the struct in the add function, and returns it:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char ch;
char str[20];
} Item;
Item* add(char* str, char ch);
int main(int argc, char const *argv[]){
int i;
int n = 3; // number of elements in the array
Item** arr = malloc(n * sizeof(Item*));
arr[0] = add("cap", 'k');
arr[1] = add("foo", 'i');
arr[2] = add("bar", 'j');
printf("%c\n", arr[0]->ch );
printf("%s\n", arr[0]->str );
for (i = 0; i < n; i++)
free(arr[i]);
free(arr);
return 0;
}
Item* add(char* str, char ch) {
Item *i = malloc(sizeof *i);
strcpy(i->str, str);
i->ch = ch;
return i;
}

Passing multiple strings into a function

i am trying to read several strings into a function for processing. The instructions are to pass each string into the function (not create a 2d array of strings). The parameters must stay the same. Here is what i tried
#include <stdio.h>
#include <math.h>
void convert(char s[]), int counts[]);
int main(void)
{
int i = 0;
int d[2] = {};
char text0[] = "this IS a String 4 you.";
char text1[] = "This sample has less than 987654321 leTTers.";
while(i<2)
{
convert (text[i],d); """ this is wrong but i dont know how to correctly do this
i = i +1;
}
}
void convert(char s[]), int counts[])
{
printf("%s this should print text1 and text2", s );
}
So i have a couple of questions. Is there some sort of special character/operator similiar to the glob module in python that can correctly do the convert (text[i],d) part for me where i try to read in each string. Also the int counts[] purpose is to be filled in with the word and character count in the function. So if i fill in this array in function convertwill main also recognize it since i need to print the word/character count in main without returning the actual counts in convert
You could use temporary string pointer array to pass all strings:
char text1[] = "This sample has less than 987654321 leTTers.";
char const * texts[] = { text0, text1 };
convert (texts, 2, d);
}
void convert(char const * s[], size_t n, int counts[])
{
while(n--) {
*counts++ = strlen(*s);
printf("%s\n", *s++);
}
}
Some notes:
I added char const to function argument type. You should always do that when function does not change the string. If you need to change the string in function, just remove the const.
There is extra argument size_t n to pass array array element count to function. size_t can be found in stddef.h.
i think u lost a "(" in "void convert(char s[]), int counts[]);".
it should be void convert((char s[]), int counts[]);
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void convert(char s[], int counts[]);
int main(void){
int i = 0;
int d[2] = {0};
char text0[] = "this IS a String 4 you.";
char text1[] = "This sample has less than 987654321 leTTers.";
char *text[] = { text0, text1 };
for(i=0; i<2; ++i){
convert (text[i], d);
printf("%d, %d\n", d[0], d[1]);
}
}
void convert(char s[], int counts[]){
printf("%s\n", s );
{
char *temp = strdup(s);
char *word, *delimiter = " \t\n";//Word that are separated by space character.
int count_w=0, max_len=0;
for(word = strtok(temp, delimiter); word ; word = strtok(NULL, delimiter)){
int len = strlen(word);
if(max_len < len)
max_len = len;
++count_w;
}
counts[0] = count_w;
counts[1] = max_len;
free(temp);
}
}

Resources