2

我想将该gets()功能用于std::string str. 但我收到一个错误:

从 'const char*' 到 'char*' 的无效转换

strlen()另一方面,当我写的时候,这个函数没有给出任何错误

int len = strlen(str.c_str())

gets(NUM.c_str())给出了错误。

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

4

4 回答 4

9

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

即使您确实规避了这一点(您确实不应该这样做),也无法更改字符串的大小(正如您尝试做的那样),因为这是由string对象管理的。您可以做的最好的事情是覆盖可能不属于 的内存string,从而导致崩溃或其他未定义的行为。

即使您确实有一个合适的数组可以写入,也不要使用gets. 如果输入行太长,没有办法防止它溢出缓冲区。至少自 1999 年以来,它在 C 中已被弃用。

有什么建议么?

std::getline(std::cin, NUM);
于 2013-08-22T18:19:13.723 回答
5

从哪里开始...

(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对象一起工作,因此您无需担心缓冲区的大小。

于 2013-08-22T18:19:58.587 回答
0

我想使用gets() 函数

gets()是 C。如果可能,最好使用 C++ 特性

而是尝试这样的getline:-

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

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

让世界变得更美好——不要使用gets

于 2013-08-22T18:18:39.483 回答
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

关于为什么你不应该使用的解释和示例: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
于 2013-08-22T18:19:53.330 回答