我正在尝试重新编程,特别是控制台游戏。我听说诅咒对此有好处,所以我找到了一个curses教程,我正在进入。我正在使用C ++,当然我想利用std :: string,但像getstr()
这样的函数只接受char *。有没有办法将字符串作为char *传递,或者我将不得不放弃使用C ++字符串?
答案 0 :(得分:8)
您仍然可以使用C ++ std::string
,但是您必须将内容复制到缓冲区(std::vector<char>
会很好)并在使用期望可写{{1}的函数时将其复制回来缓冲区。
答案 1 :(得分:5)
可以安全地传递给期望可修改 C风格数组的函数的唯一C ++容器是std::vector
(不要忘记resize()
它或创建它足够大从一开始)和boost::array
(或自{+ 1}以来的C ++ 11)。
答案 2 :(得分:1)
如果库任意修改内容和长度,这将很难管理。您可以尝试使用an existing C++ wrapper on CURSES。或this one(有点旧......)。
NCURSES built-in C++ bindings。不知道你在做什么实现,但检查这个。
答案 3 :(得分:0)
如果你想把字符串放到这样的函数中,你当然可以使用c_str();
getstr(string.c_str());
此外,std :: string还包含const char string::data(),它返回指向当前字符串中第一个字符的指针(但不是以null结尾!)。
但在此函数中无法更改此字符串(以上述方式之一)。
但你可以这样做:
change_c-str(char* str, int size);
//...
string str = "foo";
char arr[str.size()+1];
strcpy(arr, str.c_str());
change_c-str(arr, str.size()); //this is valid as long as change_c-str won't put string which is longer than size
答案 4 :(得分:0)
现在是真实但非法的答案。我曾经使用的所有std :: string实现都很高兴让你破解字符串数据
char *naughty = const_cast<char*>(myStr.c_str());
naughty[3] = 'f';
这是有效的。你不能改变长度。请注意,在字符串外部建立索引会使真正糟糕的事情发生,但那时候,无论如何都是真实的
答案 5 :(得分:0)
正如其他人所说,你必须将函数包装在一个副本中,然后从C风格的缓冲区中返回。这个使用短生命包装器对象的解决方案非常优雅:
using namespace std;
class Wrap {
public:
Wrap(string &S,int Length):Buffer(Length),Orig(S)
{ //constructor copies the string to the buffer
copy(Orig.begin(),Orig.end(),&Buffer[0]);
cout<<"Construct\n";
}
~Wrap()
{ //destructor copies the buffer contents back to the string
Orig=&Buffer[0];
cout<<"Destruct\n";
}
operator char*() { return &Buffer[0]; }
vector<char> Buffer;
string &Orig;
};
void Func(char *T) //a typical C-Style function that modifies the string
{
cout<<"Function\n";
*(T+1)='Q';
*(T+2)='Q';
}
int main()
{
string X("Hiya");
Func(Wrap(X,20)); //Call the function with a wrapped string
cout<<X; //output the modified string
}
此代码输出:
Construct
Function
Destruct
HQQa
演示了它是如何工作的。这不能解决您必须指定缓冲区长度的问题,但它允许调用的函数更改字符串的长度和内容(最多为指定的缓冲区大小)。