使用std :: string作为字符数组

时间:2013-08-22 18:11:58

标签: c++ string

我想对gets()使用std::string str函数。但是我收到了一个错误:

  

从'const char *'无效转换为'char *'

另一方面,strlen()函数在写

时不会出现任何错误
int len = strlen(str.c_str())

但是gets(NUM.c_str())会出错。

有什么建议吗?我需要使用std::stringgets(),因为我的字符大小未知。

4 个答案:

答案 0 :(得分:9)

c_str()返回指向字符串内容的const指针,因此您无法使用它来修改字符串。

即使你确实绕过了(你真的不应该这样),也不可能改变字符串的 size (正如你想做的那样),因为那是由管理的string对象。您可以做的最好的事情是写入string可能不拥有的内存,导致崩溃或其他未定义的行为。

即使你有一个合适的数组要写,也不要使用gets。如果输入行太长,则无法阻止它溢出缓冲区。至少自1999年以来,它已在C中弃用。

  

有什么建议吗?

std::getline(std::cin, NUM);

答案 1 :(得分:5)

从哪里开始...

(1)首先,gets需要char*,但std::string::c_str()会返回const char*std::string::c_str()的目的仅仅是提供字符串数据的C字符串表示 - 它并不意味着提供可写缓冲区。函数gets需要可写字符缓冲区。

(2)其次,您可以使用std::string运算符将[]用作可写字符缓冲区,并说:

std::string s(100); // create a buffer of size 100
char* buf = &s[0];

这保证在C ++ 11中正常工作,但是在早期版本的C ++中,并不一定能保证std::string提供连续的内存缓冲区。 (虽然在实践中,它几乎总是如此。)但是,如果你想要一个缓冲区,最好使用std::vector<char>

(3)最后,不要使用gets,永远。它非常危险并且使您的程序容易出现缓冲区溢出和shellcode注入攻击。的问题是,gets没有按&#39;吨包括size的参数,因此在实践中,程序将读取的字节的任何任意量到缓冲器,潜在溢出缓冲器,并导致未定义的行为。这在历史上一直是许多黑客的攻击载体,especially when gets is used with a stack array。应该在C中使用函数fgets,因为它允许您指定最大读取大小参数。在C ++中,使用std::getline会更好,因为它直接与std::string对象一起使用,因此您不必担心缓冲区的大小。

答案 2 :(得分:0)

  

我想使用gets()函数

gets()是C.如果可能,最好使用C ++功能

而是像这样尝试getline: -

std::getline(std::cin, NUM);

正如Jrok在评论中提到的那样: -

让世界变得更美好 - 不要使用获取

答案 3 :(得分:0)

除了首先尝试使用gets的问题之外,你不能在c_str()返回的缓冲区上使用它,因为缓冲区是一个const char *(它指向字符串std::string对象持有的缓冲区。如果你坚持使用gets(),你需要创建自己的缓冲区来读入:

char buffer[1024] = {0}; // temporary buffer
gets(buffer); // read from stdin into the buffer
std::string s(buffer); // store the contents of the buffer in a std::string

有关您绝不应使用getshttp://www.gidnetwork.com/b-56.html

的原因的说明和示例

更好的方法是

std::string s; // the std::string you are using
std::getline(std::cin, s); // read the line