我想对gets()
使用std::string str
函数。但是我收到了一个错误:
从'const char *'无效转换为'char *'
另一方面,strlen()
函数在写
int len = strlen(str.c_str())
但是gets(NUM.c_str())
会出错。
有什么建议吗?我需要使用std::string
和gets()
,因为我的字符大小未知。
答案 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
有关您绝不应使用gets
:http://www.gidnetwork.com/b-56.html
更好的方法是
std::string s; // the std::string you are using
std::getline(std::cin, s); // read the line