sprintf':无法将参数1从'const char *'转换为'char *'

时间:2014-09-25 07:56:56

标签: c++ visual-c++

std::string mystring;

sprintf(mystring.c_str(), "%s %d", "Helloworld", 2014);

它给我一个编译器错误:

'sprintf' : cannot convert parameter 1 from 'const char *' to 'char *'

6 个答案:

答案 0 :(得分:10)

它不应该是一个警告,应该是一个错误。指针 由std::string::c_str()返回指向只读内存; 任何通过它写的尝试都是未定义的行为。 (在你的 如果您使用const_cast来关闭编译器,那么就是这样 代码可能会崩溃,因为你正在调用c_str() 空的strying。)

一般来说,你可能想要的是 std::ostringstream

std::ostringstream formatter;
formatter << "Helloworld" << ' ' << 2014;
std::string myString = formatter.str();

FWIW:sprintf是其中最危险的功能之一 标准库,仅出于历史原因。它的 几乎不可能安全使用;即使在C中,你也应该选择 snprintf(但在C ++中,std::ostringstream要好得多。)

答案 1 :(得分:9)

您的警告会为您提供所需的所有信息。

std::string::c_str()返回const char*,sprintf需要char*,因为它会修改缓冲区。

但是你正在编写c ++并且应该避免使用sprintf。使用ostringstream将格式化数据写入字符串。

答案 2 :(得分:2)

std::string管理底层的C风格缓冲区。 c_str返回const char *,因为它不应该被字符串方法之外的任何东西修改。

您应该使用ostringstream。请参阅此问题:C++ equivalent of sprintf?

答案 3 :(得分:2)

您告诉sprintf将结果存储在mystring.c_str()中。这是mystring的基本表示的只读视图。由于它是只读(或const char *),因此无法将结果写入其中。

如果你需要使用sprintf,你必须创建一个可写的字符缓冲区供它使用,然后将该缓冲区分配给mystring。

在不必创建字符缓冲区和处理可能的溢出的情况下执行此类操作的另一种方法是使用stringstream

std::stringstream buffer;
buffer << "Helloworld " << 2014;
mystring = buffer.str();

答案 4 :(得分:0)

或者,将旧的C snprintf用于临时缓冲区,然后分配到字符串中:

 std::string mystring;
 char buf[64];
 snprintf(buf, sizeof(buf), "%s %d", "Helloworld", 2014);
 mystring.assign(buf);

snprintf总是比sprintf更安全,因为它避免了buffer overflow

但是当然使用像here by James Kanze这样的ostringstream更好。

答案 5 :(得分:0)

#include <iostream>
#include <string>
#include <sstream>  

 std::stringstream ss;
 ss << "Helloworld";
 ss << " ";
 ss << "2014";
 ss << std::endl;
 std::string str = ss.str();
 std::cout << str;

 const char * mystring= str.c_str();

这样你也可以在字符串中附加int或long数字。

示例:

 long year = 2014;

 std::stringstream ss;
 ss << "Helloworld";
 ss << " ";
 ss << year;
 ss << std::endl;
 std::string str = ss.str();
 std::cout << str;

 const char * mystring= str.c_str();