C updating string incrementally

101 Views Asked by At

I am trying to update string step by step in C. The code i tried is below:

#include <stdlib.h>
#include <stdio.h>

int writech(char **text, char ch) {
    **text = ch;

    return 1;
}

char *write(int array[], size_t size) {
    char *string = (char*)malloc(sizeof(char)*(size+1));
    int i, n;

    for (i = 0; i < size; ++i) {
        n = writech(&string, '0' + array[i]);
        string += n;
    }

    return string;
}

int main() {
    int arr[] = { 1, 2, 3, 4, 5 };
    char *str = write(arr, sizeof(arr)/sizeof(arr[0]));

    printf("%s\n", str);

    return 0;
}

Here, write function should update string by calling other function and return updated string at the end. The code compiled and run successfully, though str (at the end of main) is empty after all. Actually, my task is to create string that contain table of some data and return it at the end. Pseudo code for my idea is below:

char *render_table() {
    char *table = malloc(sizeof table);

    write_header(table);
    write_row(table, some_data);
    write_row(table, some_data);
    write_footer(table)

    return table;
}

For implementing this pseudo code I wrote the above code, but not able to update passed string successfully. I know pointers are passed to function as copies, and passed memory of my string (writech(&string) to function, but string not updated still. What am i missing?

P.S. Tweaking with pointers is really struggling for me as beginner in C. What would you suggest?

3

There are 3 best solutions below

2
On BEST ANSWER

string is updated. The problem is the pointer string is updated and the information of the beginning of the string is lost. You have to hold the information.

One more point is that terminating null-character must be added to pass the buffer for %s (without specifying length to print).

Also note that casting results of malloc() in C is discouraged.

Try this:

char *write(int array[], size_t size) {
    char *string = malloc(sizeof(char)*(size+1));
    char *cursor = string;
    int i, n;

    for (i = 0; i < size; ++i) {
        n = writech(&cursor, '0' + array[i]);
        cursor += n;
    }
    writech(&cursor, '\0');

    return string;
}
5
On

Seems to me that you are making this much more complicated than needed.

Simply do:

for (i = 0; i < size; ++i) {
    string[i] = '0' + array[i]);
}
string[i] = '\0';

If for some reason you really want to use the writech function, you can change it to:

void writech(char *text, char ch) {
    *text = ch;
}

and call it like:

for (i = 0; i < size; ++i) {
    writech(string + i, '0' + array[i]);
}
string[i] = '\0';

but it's really just making a simple task complex.

EDIT due to comment

If you (in your real code) don't know how many chars will be added by a function call, you simply do:

int writeSomethingA(char* str, ... other arguments ...)
{
    // update str, e.g. like str[0] = 'a'; str[1] = 'b';
    //                  or strcpy(str, "Some text");

    return NumberOfCharAdded;
}

(make similar B and C versions)

and call them like:

char* string malloc(....);
int idx = 0;

idx += writeSomethingA(string + idx, ... other arguments ...);

idx += writeSomethingB(string + idx, ... other arguments ...);

idx += writeSomethingC(string + idx, ... other arguments ...);

string[idx] = '\0';
0
On

For starters it is unclear why the function writech

int writech(char **text, char ch) {
    **text = ch;

    return 1;
}

has the first parameter with the type char ** instead of char *.

The function can be defined like

int writech( char *text, char ch ) {
    *text = ch;
    return 1;
}

Within the function write the pointer string is being changed in the for loop. So the function returns a pointer that does not point to the beginning of the allocated memory.

Also as you are using the conversion specifier %s to output the character array in main then the array shall contain a string. That is the array shall have contain the terminating zero character '\0'.

The function can be implemented the following way

char * write( const int array[], size_t size ) {
    char *string = malloc( size + 1 );

    if ( string != NULL )
    {
        char *p = string;

        while ( size-- ) {
            p +=  writech( p, '0' + *array++ );
        }

        *p = '\0';
    }

    return string;
}

And you should free the allocated memory before exiting main like

free( str );