提问人:yasara malshan 提问时间:1/2/2020 最后编辑:Sid Syasara malshan 更新时间:1/3/2020 访问量:299
如何在 C 中使用 sprintf 回推另一个字符串
How to use sprintf to pushback another string in C
问:
我需要将另外几个具有给定尾随模式的字符串推回/附加到 C 中的现有 char 数组中。 为了实现这一点,我愿意使用“sprintf”,如下所示。
#include <stdio.h>
#include<string.h>
int main()
{
char my_str[1024]; // fixed length checked
char *s1 = "abcd", *s2 = "pqrs";
sprintf(my_str, "Hello World"); // begin part added
sprintf(my_str, "%s , push back '%s' and '%s'.", my_str, s1, s2); // adding more to end of "my_str" (with given trailling format)
/* here we always use 'my_str' as the first for the string format in sprintf - format starts with it */
return 0;
}
当我遵循此方法时,我收到“内存重叠”警告。这是一个严重的问题吗?(如内存泄漏、错误输出等)
答:
2赞
Barmar
1/2/2020
#1
之所以出现此警告,是因为不允许对输入参数的输出和其中一个输入参数使用相同的字符串。规范说:sprintf()
如果在重叠的对象之间进行复制,则行为是未定义的。
对输出使用新字符串。
#include <stdio.h>
#include<string.h>
int main()
{
char my_str[1024], my_str2[1024]; // fixed length checked
char *s1 = "abcd", *s2 = "pqrs";
sprintf(my_str, "Hello World"); // begin part added
sprintf(my_str2, "%s , push back '%s' and '%s'.", my_str, s1, s2); // adding more to end of "my_str" (with given trailling format)
return 0;
}
评论
0赞
yasara malshan
1/2/2020
我的观点是,当格式字符串以“%s”开头时(例如:“%s<anything>”),似乎可以为输入和输出添加相同的字符串。(因为,在我添加“printf(”%s“, my_str);”后,我在“onlinegdb.com/online_c_compiler”中收到正确的输出“Hello World,push back 'abcd' and 'pqrs'.”
1赞
Barmar
1/3/2020
我从规范中添加了不允许的引用。仅仅因为它在您尝试时有效,并不意味着它通常没问题。
7赞
Sid S
1/2/2020
#2
调用时不允许对输入和输出使用相同的字符串sprintf()
因此,请替换以下内容:
sprintf(my_str, "%s , push back '%s' and '%s'.", my_str, s1, s2);
有了这个:
sprintf(my_str + strlen(my_str), " , push back '%s' and '%s'.", s1, s2);
评论
0赞
yasara malshan
1/2/2020
我的观点是,当格式字符串以“%s”开头时(例如:“%s<anything>”),似乎可以为输入和输出添加相同的字符串。(因为,在我添加“printf(”%s“, my_str);”后,我在“onlinegdb.com/online_c_compiler”中收到正确的输出“Hello World,push back 'abcd' and 'pqrs'.”)
1赞
Jonathan Leffler
1/2/2020
@yasaramalshan — 未定义行为的问题在于,它似乎可以按照您的预期工作(即使您的期望是没有根据的),但它随时可以以不同的方式工作,除了修复代码之外,您无能为力,因为您违反了对如何安全使用的限制。不要依赖目前在您的机器上碰巧起作用的未定义行为;它可能再也行不通了。sprintf()
1赞
Bob Shaffer
1/2/2020
此处显示的解决方案消除了重叠,应该没问题。但是,我建议使用 snprintf 并在添加字符串时跟踪字符串长度(snprintf 返回打印的字符数),以便您可以只使用 (buffer_size - total_printed) 之类的东西作为大小参数并避免缓冲区溢出。您还可以使用该值来避免不必要地调用 strlen()。
评论
strcat
。sprintf()