带有%s和std::string的sprintf会发出胡言乱语
sprintf with %s and std::string gives gibberish
在以下代码中:
#include <string>
using namespace std;
int main(){
char command[300];
string stringz = "mystringy";
sprintf(command,"echo "something with a string %s" ", stringz);
system(command);
return 0;
}
为什么输出
something with a string 8�
而不是预期的
something with a string mystringy
一个愚蠢的问题,但我找不到答案。
printf的"%s"修饰符采用char*
,而不是std::string
。
你可以写:
sprintf(command,"echo "something with a string %s" ", stringz.c_str());
它为std::string
的内容提供了一个const char*
。这显示了sprintf
的一个主要弱点——没有类型检查!
sprintf
格式的%s
需要一个C字符串,这是一个以0结尾的char
数组,而不是std::string
。
stringz.c_str()
和由于C++11&stringz[0]
和stringz.data()
是获取std::string所持有的C字符串的几种方法。
要添加Deduplicator
答案,请尝试放置
sprintf(command,"echo "something with a string %s" ", stringz.c_str());
你应该做好准备。
这是因为sprintf
需要一个char *
作为扩展%s
令牌的参数。它会像一样工作
sprintf(command,"echo "something with a string %s" ", stringz.c_str());
它将字符串的"char *
"版本传递给sprintf
。
它之所以显示这些奇怪的字符,是因为整个std::string
对象被复制到sprintf
的堆栈帧中。然后,接受可变数量参数的sprintf
会查看自己的堆栈空间,并假设它要找到的是char *
,但实际上是一些垃圾,这些垃圾是将字符串数据重新解释为char *
产生的,当它被取消引用时,它会进入该序列。如果你运气不好的话,还不如分手。
首先不应该使用sprintf
。这是C++,而不是C。std::string
以一种非常自然的方式支持级联,使用+
运算符,就像在其他一些编程语言中一样:
#include <string>
int main(){
std::string stringz = "mystringy";
std::string command = "echo "something with a string " + stringz + "" ";
system(command.c_str());
return 0;
}
如果您坚持使用char
-像sprintf
这样的数组函数,请使用stringz.c_str()
。事实上,这也是system
的要求。但请注意,我的示例是如何仅在最后可能的情况下转换字符串的。
您可以使用:
sprintf(command,"echo "something with a string %s" ", stringz.c_str());
注意,%s
采用C字符串,而不是std::string
。
更好地使用iostreams
:
string stringDemo("MYSTRING");
std::cout << stringDemo << "n";
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- 使用 sprintf 将十六进制0xAABBCC转换为字符串"AA:BB:CC"
- 高精度双精度的 Sprintf 格式化问题
- sprintf(b, "%" ) 是否定义了?
- 使用 sprintf 追加到字符数组
- redefine printf(), sprintf(), etc. arm-none-eabi toolchain
- 使用 sprintf 和 %g 将双精度转换为字符串的意外结果
- C++我应该用什么来保存格式化为字符串变量(如sprintf())的文件
- 将文本文件读取到2D数组中,但数组开始为超过数组[39][]的任何内容输出胡言乱语
- 有没有办法自动实现 sprintf 的缓冲区分配?
- 在 sprintf 中从 'signed char*' 到 'char*' 的转换无效
- Arduino 到 C++ 串行读取胡言乱语
- 需要将 sprintf 格式加倍并返回太长的字符串
- 代码中的"sprintf"用法是否需要释放内存?
- 使用 sprintf 和 sscanf 将给定数字中的所有 0 替换为 5
- sprintf() 正在添加一个额外的变量
- 对 sprintf 可变参数使用一个指针
- 如何使用sprintf将UINT_64的数组添加到一个字符数组中
- 在 sprintf 函数中添加逗号
- 带有%s和std::string的sprintf会发出胡言乱语