我遇到gets
的问题。
目的是从用户那里获得输入,直到他点击“回车”。
这是代码:
struct LinkedListNode* executeSection2()
{
char inputArr [3] = {'\0'};
struct LinkedListNode* newNode;
struct LinkedListNode* head = NULL;
gets (inputArr);
while (inputArr[0] != 0) // The user didn't press "Enter"
{
newNode=newLinkedListNode();
newNode->tree=newHuffmanNode(inputArr[0],atoi(inputArr+2));
head = addNode(&head, newNode);
gets (inputArr);
}
head = buildHuffmanTree(&head);
return head;
}
似乎没问题,用户点击'Enter',代码从while出来,但在返回后,我收到错误信息:
变量'inputArr'周围的堆栈已损坏
我想我没有正确读取键盘输入。 我会很高兴看到一些指导。
感谢。
答案 0 :(得分:11)
此错误完全说明了gets
被弃用的原因:它容易出现缓冲区溢出,这会损坏堆栈或任何内存碰巧接近你的结尾缓冲。当用户输入两个以上的字符时,前三个字符放入缓冲区,其余字符进入后面的内存中,导致未定义的行为。
您需要将gets
的调用替换为fgets
的调用,该调用接受缓冲区的大小,end阻止用户输入超越它:
fgets (inputArr, 3, stdin);
在每次
while
次迭代时,用户点击输入,最后,当他想要停止时,他只点击输入。
fgets
认为'\n'
部分字符串,所以当用户点击输入时,返回的字符串中唯一的字符将是'\n'
:
while (inputArr[0] != '\n') { // The user didn't press "Enter"
...
}
答案 1 :(得分:1)
C中的gets
函数是经典的缓冲区溢出函数。 gets
是使C成为安全性错误名称的功能之一。您正在遇到缓冲区溢出。只要您从不打算分发此代码,我就不会反对。但是,除了玩具程序之外,不应该使用gets
。 man page表示同样多,并通知您不执行缓冲区溢出检查。在我的Mac上,手册页说:
调用者有责任确保输入行(如果有的话)足够短以适应字符串。
至于为什么会发生这种情况,因为用户输入的数据超出了程序可以处理的数量。您的程序可以处理两个字符。它看起来不应该计算换行符。在正确编码的应用程序中,用户输入不可能以这种方式破坏内存。