简体   繁体   English

如何在 C 中连接用 sprintf 格式化的字符串

[英]How to concatenate strings formatted with sprintf in C

I have multiple sentences which are being printed in the console currently.我有多个句子目前正在控制台中打印。 I have to gather them into a string.我必须将它们收集成一个字符串。

A part of the code is:部分代码是:

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

I tried to create formatted string using sprintf, but the result is wrong.我尝试使用 sprintf 创建格式化字符串,但结果是错误的。 The length of the sentences and their count are unlimited.句子的长度和数量是无限的。

I want the output from the above code to be like:我希望上面代码的输出是这样的:

[5 plus 3 is 8and 6 minus 3 is 3] [5加3等于8,6减3等于3]

But it is:但它是:

[and 6 minus 3 is 3and 6 minus 3 is 3] [6减3等于3,6减3等于3]

How do I need to concatenate them?我需要如何连接它们? Also, the length of the sentences and their count are unlimited.此外,句子的长度及其数量是无限的。 I have difficulties in using malloc and realloc.我在使用 malloc 和 realloc 时遇到困难。 Can anyone help?任何人都可以帮忙吗?

sprintf (buffer, "and %d minus %d is %d", 6, 3, 6-3); re-writes buffer instead of concatenating.重写buffer而不是连接。 The original result of the previous sprintf() is lost.之前sprintf()的原始结果丢失了。

strcat(c, buffer); appends buffer to itself.buffer附加到自身。 As that overlaps, it is undefined behavior (UB).由于重叠,它是未定义的行为(UB)。 Do not do that.不要那样做。


Instead use the return value of sprintf() (number of characters printed) to determine the offset printing.而是使用sprintf()的返回值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);

Avoid strcat() as that requires code to iterate down the prior string, resulting in Schlemiel the Painter's Algorithm .避免使用strcat()因为它需要代码来迭代先前的字符串,从而导致Schlemiel the Painter's Algorithm Better to keep track of the string length and use that for the next sprintf() .最好跟踪字符串长度并将其用于下一个sprintf()


Better code could use snprintf() to prevent buffer overrun.更好的代码可以使用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.句子的长度和数量是无限的。

Usually a large buffer is sufficient as unlimited is not really unlimited , just potentially large.通常一个大缓冲区就足够了,因为无限并不是真正的无限,只是可能很大。 C strings are limited to SIZE_MAX . C字符串仅限于SIZE_MAX

Alternative: research non-C standard asprintf() .替代方案:研究非 C 标准asprintf()

Good program needs nice design.Simplify it.好的程序需要好的设计。简化它。

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

In order to deal with the unlimited problem, you can output to a file or other.为了处理无限问题,可以输出到文件或其他。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM