如何在 C 中连接使用 sprintf 格式化的字符串
How to concatenate strings formatted with sprintf in C
我有多个句子正在控制台中打印。我必须把它们收集成一个字符串。
部分代码为:
#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 plus 3 is 8and 6 minus 3 is 3]
但它是:
[and 6 minus 3 is 3and 6 minus 3 is 3]
我需要如何连接它们?此外,句子的长度和数量是无限的。我在使用 malloc 和 realloc 时遇到困难。有人可以帮忙吗?
sprintf (buffer, "and %d minus %d is %d", 6, 3, 6-3);
重写 buffer
而不是连接。前面sprintf()
的原始结果丢失了。
strcat(c, buffer);
将 buffer
附加到自身。由于重叠,它是 未定义的行为 (UB)。不要那样做。
而是使用 sprintf()
(打印的字符数)的 return 值来确定胶印。
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);
length of the sentences and their count are unlimited.
通常大缓冲区就足够了,因为 unlimited 并不是真正的 unlimited,只是可能很大。 C 字符串限制为SIZE_MAX
.
备选方案:研究非 C 标准 asprintf()
。
好的节目需要好的design.Simplify它。
#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;
}
为了处理无限的问题,可以输出到文件或者其他。
我有多个句子正在控制台中打印。我必须把它们收集成一个字符串。
部分代码为:
#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 plus 3 is 8and 6 minus 3 is 3]
但它是:
[and 6 minus 3 is 3and 6 minus 3 is 3]
我需要如何连接它们?此外,句子的长度和数量是无限的。我在使用 malloc 和 realloc 时遇到困难。有人可以帮忙吗?
sprintf (buffer, "and %d minus %d is %d", 6, 3, 6-3);
重写 buffer
而不是连接。前面sprintf()
的原始结果丢失了。
strcat(c, buffer);
将 buffer
附加到自身。由于重叠,它是 未定义的行为 (UB)。不要那样做。
而是使用 sprintf()
(打印的字符数)的 return 值来确定胶印。
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);
length of the sentences and their count are unlimited.
通常大缓冲区就足够了,因为 unlimited 并不是真正的 unlimited,只是可能很大。 C 字符串限制为SIZE_MAX
.
备选方案:研究非 C 标准 asprintf()
。
好的节目需要好的design.Simplify它。
#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;
}
为了处理无限的问题,可以输出到文件或者其他。