Ram Sharma
Ram Sharma

Reputation: 59

code only take 2 inputs although it has 3 fgets

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

int main(){
    int num;
    scanf("%d",&num);  // The input is 3 so i use it to simplify the question 
    char array[num][1000];
    fgets(array[0],1000,stdin);
    fgets(array[1],1000,stdin);
    fgets(array[2],1000,stdin);
    printf("%s %s %s",array[0],array[1],array[2]);
}

The first input i.e. for scanf is 3 then i input mahatma and the gandhi. Now it should ask for another input for the last fgets but the programme ends printing mahatma gandhi. I however i do not use scanf then the result is correct. If possible please provide a code. P.S- I am using fgets for the 1st time so there may be a very basic mistake.

Upvotes: 1

Views: 529

Answers (3)

xing
xing

Reputation: 2508

Consider using fgets for all input. Parse as needed with sscanf or others.
Check the return of fgets and sscanf as that will indicate problems.
The do/while loop will continue until a positive integer is processed.
Include prompts to clarify the expected inputs.

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

int main(){
    char input[50] = "";
    int num = 0;
    int loop = 0;
    int valid = 0;

    do {
        printf ( "enter an integer\n");
        if ( fgets ( input, sizeof input, stdin)) {
            if ( 1 != ( valid = sscanf ( input, "%d", &num))) {// 1 means successful scan on an integer
                valid = 0;
                printf ( "try again to enter an integer\n");
            }
        }
        else {// fgets could not get input
            fprintf ( stderr, "problem with input\n");
            return 0;
        }
    } while ( !valid || num < 0);

    char array[num][1000];

    for ( loop = 0; loop < num; loop++) {
        printf ( "enter text for array[%d]\n", loop);
        if ( fgets(array[loop],sizeof array[loop], stdin)) {
            array[loop][strcspn( array[loop], "\n")] = '\0';// remove trailing newline if any
        }
        else {
            fprintf ( stderr, "problem with input\n");
            return 0;
        }
    }

    for ( loop = 0; loop < num; loop++) {
        printf("%s ", array[loop]);
    }
    printf("\n");
}

Upvotes: 1

Vishwajeet Vishu
Vishwajeet Vishu

Reputation: 492

Just provide a space in scanf()like this

scanf("%d ",&num);

this will make calling fgets three times(Just for this case as pointed by Peter). This is happening because when you press ENTER key after scanf() in STDIN buffer \n is stored and that gets into first fgets() call.

Upvotes: 0

Peter
Peter

Reputation: 36597

The reason, as xing noted in comments, is that scanf() leaves a newline in the stream (represented by the file handle stdin) that will be read by the first call of fgets(), causing it to return immediately.

The general solution is not to mix formatted input (like scanf()) with line oriented input (like fgets()) on the same input stream, since they will interact in unexpected ways. Your example here (scanf() leaving a newline to be read, and fgets() returning immediately due to encountering the newline) is one of many possible consequences of mixing styles of input on the same stream.

One way is to use fgets() to read data to a string, and then read an int from that string using sscanf(). The interaction with stdin then ONLY uses fgets().

Another option would be to change all the usages of fgets() to use scanf(). This will require finding a sensible format (bearing in mind that scanf() stops reading something when it encounters whitespace - although there are some format specifiers that change this).

The advice of adding a space to the scanf() format string is flawed. It works for specific cases (like this one), but not for others. For example, if you do a loop of the form

// assume variables declared as in the OP's question

while (some_condition_that_is_true_more_than_once())
{
    scanf("%d ",&num);
    fgets(array[0],1000,stdin);
    fgets(array[1],1000,stdin);
    fgets(array[2],1000,stdin);
}

there will still be a potential interaction (depending on what the user inputs) that gives unexpected results due to interaction of the last call of fgets() in the loop with the scanf() call in the next iteration.

Upvotes: 2

Related Questions