简体   繁体   中英

Reading of standard input with fgets not waiting for input

Having this piece of code:

int main(void)
{
    char str[4];

    do
    {
        if (fgets(str,sizeof(str),stdin) == NULL)
            break;
        printf("\n %s \n", str);
    }while (strncmp(str,"q\n",sizeof("q\n")));

    return 0;
}

if i type more than 4 characters, then two lines are displayed. if i type 123456 and then press enter, does input store ['1','2','\\n','\\0'] or ['1','2','3','\\0']? hen the second time printf is reached if i only press enter key one time?. How i can avoid this behaviour? I would like type 123456 and then get:

1234 

The reason why fgets is only reading partial input is because the str array is too small. You need to increase the buffer size of str array.

Also remember that fgets will pick up \\n ( enter / return ) that you press after giving your input.

To get rid of the \\n do this:

fgets(str,sizeof(str),stdin);
str[strlen(str)-1] = '\0';

There is one MAJOR issue with your while condition ... I am not sure what your are trying to do there but strcmp is used to see if two strings are the same or not ... what you are doing is trying to compare a string to the size of something ...

There are multiple problems in your code:

  • you do not include <stdio.h> .

  • fgets() is given a very short buffer: 4 bytes, allowing for only 3 characters to be input at a time, including the '\\n' . If you type more characters, they are buffered by the terminal and the standard stream library. It will take several calls to fgets() to read them all, 3 bytes at a time.

  • Your termination test is bogus: strncmp(str, "q\\n", sizeof("q\\n")) compares the string read by fgets() with "q\\n" upto a maximum number of characters of 3 because sizeof("q\\n") counts the q , the \\n and the null terminator. You should just use strcmp() for this test.

  • You print the string with printf("\\n %s \\n", str); . Note however that a regular line read into str will contain the trailing newline so the printf call will actually output 2 lines.

Here is a modified version:

#include <stdio.h>
#include <string.h>

int main(void) {
    char str[80];

    while (fgets(str, sizeof(str), stdin) != NULL) {
        str[strcspn(str, "\n")] = '\0';  // strip the newline if present
        printf("\n %s \n", str);
        if (!strcmp(str, "q"));
            break;
    }
    return 0;
}

Try using getc() or fgetc() before using fgets()

When you use a scanf() , you press enter key (newline) which operates as accepting the input and transferring the input from stdin (standard input device) to your program.

scanf() itself does not consume the newline pressed. So, we need something down the code which will accept this newline and prevent this newline from acting as an input to the subsequent fgets() . This newline can be accepted using getc() or fgetc() , which should be written before fgets() .

fgetc(stdin); OR getc(stdin) ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM