在以下代码中:
#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
一个愚蠢的问题,但我无法找到答案。
答案 0 :(得分:6)
printf的'%s'修饰符需要char*
,而不是std::string
。
你可以写:
sprintf(command,"echo \"something with a string %s\" ", stringz.c_str());
这为const char*
的内容提供了std::string
。这显示了sprintf
的一个主要缺点 - 没有类型检查!
答案 1 :(得分:4)
sprintf
格式%s
需要一个C字符串,这是一个以char
为单位的0终止数组,而不是std::string
。
stringz.c_str()
因为C ++ 11 &stringz[0]
和stringz.data()
是获取std :: string所持有的C字符串的几种方法。
答案 2 :(得分:2)
要添加Deduplicator
答案,请尝试添加
sprintf(command,"echo \"something with a string %s\" ", stringz.c_str());
你应该被设置。
答案 3 :(得分:2)
这是因为sprintf
期望char *
作为参数来扩展%s
令牌。它会像
sprintf(command,"echo \"something with a string %s\" ", stringz.c_str());
将字符串的“char *
”版本传递给sprintf
。
它显示那些奇怪字符的原因是因为整个 std::string
对象被复制到sprintf
的堆栈帧中。然后,sprintf
接受可变数量的参数,查看它自己的堆栈空间,并假设它将找到的是char *
,但实际上是重新解释字符串导致的一些垃圾数据为char *
,当它被解除引用时,它会产生该序列。如果你运气不好,那也可能是段错误。
答案 4 :(得分:2)
您不应该首先使用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
所要求的。但请注意我的示例仅在最后一次可能的情况下转换字符串。
答案 5 :(得分:1)
您可以使用:
sprintf(command,"echo \"something with a string %s\" ", stringz.c_str());
请注意,%s
采用C字符串而非std::string
。
更好地使用,iostreams
:
string stringDemo("MYSTRING");
std::cout << stringDemo << "\n";