gets() taking input without actually giving it any input?

左心房为你撑大大i 提交于 2019-12-24 04:26:28

问题


I'm fairly new to C so sorry if this is a stupid question but when I run the following code:

#include <stdio.h>

int main () {
    int i;
    int test[10];
    char string[81];

    for(i = 0; i < 10; i++){
        scanf("%d", &test[i]);
    }

    for(i=0; i < 7; i++){
        gets(string);
        printf("String was entered\n");
    }

}

And enter any 10 digits, the line "string was entered" will be printed even though I didn't enter a string in the command window. Can anyone explain why? Is there any way to stop it happening?

Thanks!


回答1:


After you read in data using scanf, the newline is still sitting in the input queue waiting to be read. gets reads that newline and stops (because it's reached the end of the line!)

Note that it's a bad idea to use gets: it provides no way to put a limit on how many characters get read into the buffer, so if you type in more characters than will fit in the buffer, you'll end up overflowing the buffer, resulting in data corruption, an application crash, a huge security vulnerability, and/or any number of other unpredictable results. For a safe alternative, you can use fgets instead with stdin:

fgets(string, sizeof(string), stdin);

(Note that you'd probably want to use a symbolic constant of some kind for the size of string so that you don't repeat it in multiple places - or use sizeof(string) when the array definition is visible.)




回答2:


At a guess, scanf() didn't consume the newline that you had to type so that it could process the ten integers you wanted to get before the string. So, after the last call to scanf(), gets() is facing an input buffer that begins with a newline. Presto, it has met its spec so it copies nothing to its buffer and returns.

In general, scanf() and gets() are poor choices for new code. They both have issues that make them painful to use right, or even dangerous to use at all.

Specifically, gets() does not and cannot check its output buffer size, so it will readily overwrite whatever memory happens to be located after its buffer. That way lies corruption of global state or the stack. If it is the stack, then it is possible to exploit that to gain control of the program and make it execute arbitrary code. That is not a good thing.

It would be better to consume your input stream with fgets() which has a limit on its buffer size, and to parse it with sscanf() and other functions once read.




回答3:


the following code shall work

#include <stdio.h>
 int main () {
 int i;
  int test[10];
 char string[81],s[1];
 for(i = 0; i < 10; i++){
    scanf("%d", &test[i]);
}

gets(s);

for(i=0; i < 7; i++){
    gets(string);
    printf("String was entered\n");
 }

}

the char array s[1] was used to catch the newline character left unproessed by scanf



来源:https://stackoverflow.com/questions/3739983/gets-taking-input-without-actually-giving-it-any-input

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!