开发者

How to store a concatenation of ints and characters in a char*?

I have some integers, let's say one two and three. I wish to create a 开发者_运维知识库string such as

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

This doesn't work in C/C++. How can I store that type of value in a char*?


In C there's more than one way to do it, depending how you would like to allocate the memory[*]. For the straightforward option of allocating it from the heap:

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

Beware non-standard implementations of snprintf, that don't return the length when the buffer is exceeded. Check your documentation.

In C++, snprintf is not in the standard, and even where it is available, the above code would need to cast the result of malloc[**]. C++ adds the option of using 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.

This saves messing with buffer lengths, makes resource management easier, and avoids the risk with printf and friends that you could pass an argument of the wrong type for the format specifier. It's usually the preferred option.

It is however less flexible in some circumstances: the format is hard-wired into the code rather than contained in a format string, so it's harder to make the text configurable. It can also be a bit harder to read, for instance it's not at all uncommon to leave out a space character on the first version of any such line of code. But if you want to use the snprintf approach in C++, and snprintf is available in your implementation, then you can take advantage of C++'s easier memory management as follows:

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

[*] Note that you cannot "store" a string in a char*, because a char* is just a pointer. You can store a pointer to a string in a char*, but the string itself is a completely separate thing.

[**] because C and C++ ARE DIFFERENT LANGUAGES!


C++ isn't VB. But you have numerous options.

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

boost/format:

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

old-school (hacky, unsafe, bad, dont do it)

char buffer[1024] = {};
sprintf(buffer, "There are %d bottles on %d shelves in room number %d", one, two, three); 


sprintf is an option (as Ólafur wrote), but deprecated. Use snprintf when you can - sprintf can lead to buffer overruns and cause awful crashes and bugs if you're not very careful with the size of your buffer and inputs.

char output[256];
snprintf(output, sizeof(output), "There are %d bottles of water on %d shelves 
    in room number %d\n", one, two, three);


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


I like the stringstream approach, but I use a class to simplify its usage. See my answer to another SO question for more details:

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 *


My solution:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜