How to determine if stdin is empty

Viewed 16308

I have a little project to do for school. We have a program that generate a maze. We can put arguments to generate a different maze or even get it as a picture.

We call it like that :

./test

or

./test --arg1 val --arg2 val --etc

We have been asked to parse the argument into a file that we put in stdin like that :

./test < args.txt

Now I must be able to call the program with every one of the lines above. The line with the arguments work, the mine with the program in stdin works, but the line without anything doesnt work anymore.

So i should check if the user as sent some file in stdin i call the program with a file, else i call it the normal way. I tried with feof but it can't work since stdin won't have anything in not even eof. When i call the program without arguments or file it waits for the user to write something, which it shouldnt.

Basically my code should look like that

int main()
{
    int v;
    if (stdin!=NULL)) { //if a file has been passed "./test <test.txt"
        scanf("%d",&v);
    }
    else {  //if no files has been passed "./test "
        printf("no file forwarded \n"); 
        return 1;
    }
    if (v<50) {
        printf("you drive slow\n");
    }
    else {
        printf("you drive fast\n");
    }
    return 0;
}

But obviously (stdin != NULL) doesn't work. So is there a way to check if stdin has something in? I asked my classmate, one of them told me something about useing fgetc to get the first char and then put it back if there is really a char but when i try to use fgetc, if there is no char it waits for me to put a char in.

So how could I check if stdin is empty or if there is a file into it (without using new libraries)?

Thanks you in advance have a good day

If i am not completely clear please tell it to me i am not a native speaker and i have a bit of difficulties since it's a technical question

3 Answers

It sounds like you want to run your program based on arguments either provided on the command line or piped into it from a file. If so, you should check whether the arguments have been provided on the command line first:

if (argc > 1) {
  //parse argv
}

Then, check whether stdin is empty, and if not read the arguments in from stdin:

else if ((fseek(stdin, 0, SEEK_END), ftell(stdin)) > 0)
{
  rewind(stdin);
  char buffer[1024];
  fgets(buffer, 1024 , stdin);
  //parse args read in from stdin
}
else
{
  //no redirection
}

Okay i found a solution it is not the best one since i shouldn't use external libraries but for now it works, i hope it will be usefull for someone :

feof was a good idea but indeed it doesn't work, the reason is stdin will never have EOF in it if you worte nothing in it. So if you provide a file since you must parse the file when there is no file it will try to parse what the user types in.

first you must include

#include <unistd.h>

then

int v;
    if (!isatty(STDIN_FILENO)) //if stdin is not a terminal (a file was provided)
    {
         scanf("%d",&v);
    }
    else { //if stdin is a terminal (no file provided)
        printf("no file forwarded \n"); 
        return 1;   
    }
    if (v<50){printf("you drive slow\n");}
    else {printf("you drive fast\n");}
    return 0;

it will check if stdin is a terminal or not. This solution works but if someone has one without the use of external libraries it would be super cool !

How to determine if stdin is empty(?)

Read 1 character with getchar().

int ch = getchar();
if (ch == EOF) {
  if (feof(stdin)) puts("stdin empty");
  else             puts("stdin error"); // very rare
} else {
  ungetc(ch, stdin); // put back
  puts("stdin not empty");
}
Related