我有一些整数,比方说one
two
和three
。我希望创建一个字符串,如
char* example = "There are " + one + " bottles of water on " +
two + " shelves in room number " + three + "\n".`
这在C / C ++中不起作用。如何将这种类型的值存储在char *?
中答案 0 :(得分:7)
在C语言中,有多种方法可以执行此操作,具体取决于您希望如何分配内存[*]。对于从堆中分配它的直接选项:
len = snprintf(0, 0, "%d bottles, %d shelves, room %d\n", one, two, three);
char *result = malloc(len+1);
if (result == 0) { /* handle error */ }
snprintf(result, len+1, "%d bottles, %d shelves, room %d\n", one, two, three);
/* some time later */
free(result);
注意snprintf
的非标准实现,在超出缓冲区时不返回长度。检查您的文档。
在C ++中,snprintf
不在标准中,即使它可用,上面的代码也需要转换malloc [**]的结果。 C ++添加了使用stringstreams的选项:
std::stringsteam r;
r << one << " bottles, " << two << " shelves, room " << three << "\n";
std::string result = r.str();
// if you absolutely need a char*, use result.c_str(), but don't forget that
// the pointer becomes invalid when the string, "result" ceases to exist.
这样可以减少缓冲区长度的混乱,简化资源管理,并避免printf
和朋友的风险,你可以为格式说明符传递错误类型的参数。这通常是首选方案。
然而,在某些情况下灵活性较低:格式硬连接到代码中而不是包含在格式字符串中,因此更难以使文本可配置。它也可能有点难以阅读,例如,在任何此类代码行的第一个版本上省略空格字符并不罕见。但是如果你想在C ++中使用snprintf
方法,并且在你的实现中可以使用snprintf
,那么你可以利用C ++更容易的内存管理,如下所示:
len = std::snprintf(0, 0, "%d bottles, %d shelves, room %d\n", one, two, three);
std::vector<char> r(len+1);
std::snprintf(&r[0], r.size(), "%d bottles, %d shelves, room %d\n", one, two, three);
char *result = &r[0];
// again, "result" is only valid as long as "r" is in scope
[*]请注意,您不能在char*
中“存储”字符串,因为char*
只是一个指针。您可以在char*
中存储指向字符串的指针,但字符串本身是完全独立的。
[**]因为C和C ++是不同的语言!
答案 1 :(得分:6)
C ++不是VB。但是你有很多选择。
#include <sstream>
#include <string>
stringstream ss;
ss<< "There are " << one << " bottles of water on " << two << " shelves in room number " << three;
string s = ss.str();
#include <boost/format.hpp>
#include <string>
string s = (boost::format("There are %1% bottles on %2% shelves in room number %3%")%one%two%three).str();
char buffer[1024] = {};
sprintf(buffer, "There are %d bottles on %d shelves in room number %d", one, two, three);
答案 2 :(得分:1)
sprintf
是一个选项(如Ólafur所写),但已被弃用。尽可能使用snprintf
- 如果你不太注意缓冲区和输入的大小,sprintf会导致缓冲区溢出并导致可怕的崩溃和错误。
char output[256];
snprintf(output, sizeof(output), "There are %d bottles of water on %d shelves
in room number %d\n", one, two, three);
答案 3 :(得分:1)
#include <sstream>
std::stringstream strVal;
strVal << std::string("There are ") << one << std::string(" bottles of water on ") <<
two << std::string(" shelves in room number ") << three << std::endl;
std::string copyStr(strVal.str());
const char * example = copyStr.c_str();
答案 4 :(得分:0)
我喜欢stringstream方法,但我使用类来简化其用法。有关详细信息,请参阅我的answer至另一个SO问题:
string myString = MakeString() << "There are " << one << "
bottles of water on " << two << " shelves in room number " << three;
char * example = myString.c_str(); // if you really need a char *
答案 5 :(得分:0)
我的解决方案:
template <typename T> std::string toStr(const T& something) {
std::stringstream ss;
ss << something;
return ss.str();
}
...
std::string example = "There are " + toStr(one) + " bottles of water on " +
toStr(two) + " shelves in room number " + toStr(three) + "\n";