Kalec
Kalec

Reputation: 2881

I don't understand the behavior of fgets in this example

While I could use strings, I would like to understand why this small example I'm working on behaves in this way, and how can I fix it ?

int ReadInput() {
    char buffer [5];
    printf("Number: ");
    fgets(buffer,5,stdin);
    return atoi(buffer);
}

void RunClient() {
    int number;
    int i = 5;
    while (i != 0) {
        number = ReadInput();
        printf("Number is: %d\n",number);
        i--;
    }
}

This should, in theory or at least in my head, let me read 5 numbers from input (albeit overwriting them).

However this is not the case, it reads 0, no matter what.

I understand printf puts a \0 null terminator ... but I still think I should be able to either read the first number, not just have it by default 0. And I don't understand why the rest of the numbers are OK (not all 0).

CLARIFICATION: I can only read 4/5 numbers, first is always 0.

EDIT:

I've tested and it seems that this was causing the problem:

main.cpp

scanf("%s",&cmd);
    if (strcmp(cmd, "client") == 0 || strcmp(cmd, "Client") == 0)
        RunClient();

somehow.

EDIT:

Here is the code if someone wishes to compile. I still don't know how to fix

http://pastebin.com/8t8j63vj

FINAL EDIT:

Could not get rid of the error. Decided to simply add @ReadInput

int ReadInput(BOOL check) {
    ...
    if (check) 
       printf ("Number: ");
    ...

@ RunClient()

void RunClient() {
    ...
    ReadInput(FALSE); // a pseudo - buffer flush. Not really but I ignore 
    while (...) {                    // line with garbage data
        number = ReadInput(TRUE);
        ...
    }

And call it a day.

Upvotes: 2

Views: 571

Answers (2)

Alberto Bonsanto
Alberto Bonsanto

Reputation: 18022

char * fgets ( char * str, int num, FILE * stream );

Get string from stream.

Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.

A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str. (This means that you carry \n)

A terminating null character is automatically appended after the characters copied to str. Notice that fgets is quite different from gets: not only fgets accepts a stream argument, but also allows to specify the maximum size of str and includes in the string any ending newline character.

PD: Try to have a larger buffer.

Upvotes: 1

P.P
P.P

Reputation: 121357

fgets reads the input as well as the newline character. So when you input a number, it's like: 123\n.

atoi doesn't report errors when the conversion fails.

Remove the newline character from the buffer:

buf[5];
size_t length = strlen(buffer);
buffer[length - 1]=0;

Then use strtol to convert the string into number which provides better error detection when the conversion fails.

Upvotes: 3

Related Questions