如何在char *中存储整数和字符串联?

时间:2010-10-02 16:57:45

标签: c++ c string

我有一些整数,比方说one twothree。我希望创建一个字符串,如

char* example = "There are " + one + " bottles of water on " + 
    two + " shelves in room number " + three + "\n".`  

这在C / C ++中不起作用。如何将这种类型的值存储在char *?

6 个答案:

答案 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。但是你有很多选择。

stringstream的:

#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();

老派(hacky,不安全,不好,不要这样做)

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