我正在修改一个接受const char *并使用函数ProcessString的函数。 ProcessString是一个函数,它期望以null结尾的字符缓冲区作为char *。缓冲区中的字符可能会也可能不会被修改,如下面的函数签名所定义。为了“缩小差距”,我使用临时的std :: string:
void ProcessString( char* str );
void SomeFunction( const char* str )
{
string temp(str);
ProcessString( &temp[0] );
}
我的主要问题是关于std :: string :: operator []的保证以及上面& temp [0]返回的地址是否是一个可用的,以null结尾的缓冲区作为char *。其次,第二,有更好的方法吗?
我正在使用C ++ 03。
答案 0 :(得分:5)
在C ++ 11中只有明确定义的行为;在以前的标准中,std::string
并不保证其内部缓冲区的连续存储。
然而,尽管该代码在C ++ 11中完全没问题,但更惯用的方法是使用std:vector<char>
,这保证了自C ++ 03以来的连续存储:
void ProcessString(char* str);
void SomeFunction(char const* str)
{
// + 1 for terminating NUL
std::vector<char> temp(str, str + std::strlen(str) + 1);
ProcessString(&temp[0]); // or temp.data() in C++11
}
答案 1 :(得分:1)
我创建了一个小班来面对这类问题,我已经实现了RAII习语。
class DeepString
{
DeepString(const DeepString& other);
DeepString& operator=(const DeepString& other);
char* internal_;
public:
explicit DeepString( const string& toCopy):
internal_(new char[toCopy.size()+1])
{
strcpy(internal_,toCopy.c_str());
}
~DeepString() { delete[] internal_; }
char* str() const { return internal_; }
const char* c_str() const { return internal_; }
};
您可以将其用作:
void aFunctionAPI(char* input);
// other stuff
aFunctionAPI("Foo"); //this call is not safe. if the function modified the
//literal string the program will crash
std::string myFoo("Foo");
aFunctionAPI(myFoo.c_str()); //this is not compiling
aFunctionAPI(const_cast<char*>(myFoo.c_str())); //this is not safe std::string
//implement reference counting and
//it may change the value of other
//strings as well.
DeepString myDeepFoo(myFoo);
aFunctionAPI(myFoo.str()); //this is fine
我已经调用了DeepString类,因为它正在创建现有字符串的深层唯一副本(DeepString不可复制)。
答案 2 :(得分:0)
如果您需要从const char*
转到char *
,为什么不使用strdup,然后在ProcessString完成后释放缓冲区?
通过std::string
对我来说似乎没用。