微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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

部分代码是:

#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,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 时遇到困难。有人可以帮忙吗?

解决方法

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,5+3);
offset += sprintf (buffer + offset," and %d minus %d is %d",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,5+3);
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;

retval = snprintf (buffer + offset,6-3);
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;

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

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

句子的长度和数量没有限制。

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

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

,

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

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

int main()
{
    fprintf(stdout,5+3);
    fprintf (stdout,6-3);
    return 0;
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。