我想将该gets()
功能用于std::string str
. 但我收到一个错误:
从 'const char*' 到 'char*' 的无效转换
strlen()
另一方面,当我写的时候,这个函数没有给出任何错误
int len = strlen(str.c_str())
但gets(NUM.c_str())
给出了错误。
有什么建议么?我需要使用std::string
,gets()
因为我的字符大小是未知的。
c_str()
返回const
指向字符串内容的指针,因此您不能使用它来修改字符串。
即使您确实规避了这一点(您确实不应该这样做),也无法更改字符串的大小(正如您尝试做的那样),因为这是由string
对象管理的。您可以做的最好的事情是覆盖可能不属于 的内存string
,从而导致崩溃或其他未定义的行为。
即使您确实有一个合适的数组可以写入,也不要使用gets
. 如果输入行太长,没有办法防止它溢出缓冲区。至少自 1999 年以来,它在 C 中已被弃用。
有什么建议么?
std::getline(std::cin, NUM);
从哪里开始...
(1) 首先,gets
期望 a 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
, EVER。这是非常危险的,并且使您的程序容易受到缓冲区溢出和 shellcode 注入攻击。问题是它gets
不包含size
参数,因此实际上程序会将任意数量的字节读入缓冲区,可能会溢出缓冲区并导致未定义的行为。这在历史上一直是许多黑客的攻击媒介,尤其gets
是与堆栈数组一起使用时。fgets
应该在 C 中使用该函数,因为它允许您指定最大读取大小参数。在 C++ 中,最好使用std::getline
,因为它直接与std::string
对象一起工作,因此您无需担心缓冲区的大小。
除了首先尝试使用的问题之外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
关于为什么你不应该使用的解释和示例:http gets
: //www.gidnetwork.com/b-56.html
一个更好的方法是
std::string s; // the std::string you are using
std::getline(std::cin, s); // read the line