C增量更新字符串

C updating string incrementally

我正在尝试在 C 中逐步更新字符串。我尝试的代码如下:

#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;
}

这里,write 函数应该通过调用其他函数来更新 string,最后 return 更新 string。代码编译成功 运行,尽管 str(在 main 的末尾)毕竟是空的。实际上,我的任务是创建包含 table 一些数据并在末尾包含 return 的字符串。我的想法的伪代码如下:

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;
}

为了实现这个伪代码,我写了上面的代码,但无法成功更新传递的字符串。我知道指针作为副本传递给函数,并将我的字符串 (writech(&string) 的内存传递给函数,但 string 仍未更新。我错过了什么?

P.S. 作为 C 初学者,用指针调整真的很费劲。你有什么建议?

string 已更新。问题是指针 string 更新了,字符串开头的信息丢失了。你得拿着资料。

还有一点是必须添加终止null-character以传递%s的缓冲区(不指定要打印的长度)。

另请注意,malloc() 在 C 中的转换结果是 discouraged

试试这个:

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, '[=10=]');

    return string;
}

在我看来,你把这件事弄得比需要的复杂得多。

只需执行:

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

如果由于某种原因你真的想使用writech功能,你可以将其更改为:

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

并这样称呼它:

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

但这实际上只是让一个简单的任务变得复杂。

根据评论编辑

如果您(在您的实际代码中)不知道函数调用将添加多少个字符,您只需执行以下操作:

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

    return NumberOfCharAdded;
}

(制作类似的B版和C版)

并这样称呼他们:

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] = '[=14=]';

对于初学者来说,不清楚为什么函数 writech

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

    return 1;
}

的第一个参数类型为 char ** 而不是 char *

函数可以这样定义

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

在函数 write 中,指针 string 在 for 循环中被更改。所以函数 returns 一个不指向分配内存开头的指针。

此外,由于您使用转换说明符 %s 在 main 中输出字符数组,因此该数组应包含一个字符串。即数组应包含终止零字符 '[=19=]'.

功能可以通过以下方式实现

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 = '[=12=]';
    }

    return string;
}

而且你应该在退出 main 之前释放分配的内存,比如

free( str );