带有%s和std :: string的sprintf给出了乱码

时间:2015-07-24 10:08:59

标签: c++ string printf variadic-functions stdstring

在以下代码中:

#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

一个愚蠢的问题,但我无法找到答案。

6 个答案:

答案 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";