Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if stdin is empty

Tags:

c

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

like image 494
Rekch Avatar asked Nov 16 '17 02:11

Rekch


People also ask

Do I need to close stdin?

However, calling fclose(stdin) will work on any POSIX compliant operating system as well as Windows operating systems, so you should hit pretty much anything in general use at the moment. As stated by the previous answer as well as my comment, there is no need to call close on the file handle.

Does Getchar read stdin?

getchar is a function in C programming language that reads a single character from the standard input stream stdin, regardless of what it is, and returns it to the program.

Does stdin have a buffer?

Default Buffering modes:stdin is buffered (line buffering doesn't affect stdin) stdout is buffered (line buffered if connected to a terminal) stderr is unbuffered.


2 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
}
like image 56
mnistic Avatar answered Sep 28 '22 08:09

mnistic


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 !

like image 40
Rekch Avatar answered Sep 28 '22 08:09

Rekch