1

我有多个句子目前正在控制台中打印。我必须将它们收集成一个字符串。

代码的一部分是:

#include <stdio.h>
#include<string.h>

int main()
{
    char buffer [100];
    sprintf (buffer, "%d plus %d is %d", 5, 3, 5+3);
    char *c=buffer;
    sprintf (buffer, "and %d minus %d is %d", 6, 3, 6-3);
    strcat(c, buffer);
    printf ("[%s]",c);
    return 0;
    return 0;
}

我尝试使用 sprintf 创建格式化字符串,但结果是错误的。句子的长度和数量是无限的。

我希望上述代码的输出如下:

[5加3等于8,6减3等于3]

但它是:

[和 6 减 3 是 3 和 6 减 3 是 3]

我需要如何连接它们?此外,句子的长度和数量是无限的。我在使用 malloc 和 realloc 时遇到困难。任何人都可以帮忙吗?

4

2 回答 2

4

sprintf (buffer, "and %d minus %d is %d", 6, 3, 6-3);重写buffer而不是连接。先前的原始结果sprintf()丢失。

strcat(c, buffer);附加buffer到自身。由于重叠,它是未定义的行为(UB)。不要那样做。


而是使用sprintf()(打印的字符数)的返回值来确定胶印。

int offset = sprintf (buffer, "%d plus %d is %d", 5, 3, 5+3);
offset += sprintf (buffer + offset, " and %d minus %d is %d", 6, 3, 6-3);
offset += sprintf (buffer + offset, " even more");
printf ("[%s]",buffer);

避免strcat(),因为这需要代码迭代先前的字符串,从而导致Schlemiel the Painter's Algorithm。最好跟踪字符串长度并将其用于下一个sprintf().


可以使用更好的代码snprintf()来防止缓冲区溢出。

// Pedantic example
char buffer [100];
size_t offset = 0;
size_t available = sizeof buffer;

int retval = snprintf (buffer, available, "%d plus %d is %d", 5, 3, 5+3);
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;

retval = snprintf (buffer + offset, available, " and %d minus %d is %d", 6, 3, 6-3);
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;

retval = snprintf (buffer + offset, available, " even more");
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;

printf ("[%s]",buffer);

句子的长度和数量是无限的。

通常一个大的缓冲区就足够了,因为无限制并不是真正的无限制,只是可能很大。C字符串仅限于SIZE_MAX.

替代方案:研究非 C 标准asprintf()

于 2021-07-27T14:48:54.433 回答
0

好的程序需要好的设计。简化它。

#include <stdio.h>
#include <string.h>

int main()
{
    fprintf(stdout, "%d plus %d is %d", 5, 3, 5+3);
    fprintf (stdout, "and %d minus %d is %d", 6, 3, 6-3);
    return 0;
}

为了处理无限制的问题,您可以输出到文件或其他。

于 2021-07-27T14:55:06.437 回答