0
votes

I am writing a program that reads from a file passed as an arguement, or reads from stdin if no arguements are given. The code runs fine with a file passed, but I get a seg fault when no file is passed. I basically call fopen on argv[1] if a file was given, but if no file was given I call:

f = fopen("stdin", "r");

Is this the correct syntax for opening stdin as a file?

2
You don't need to manually open stdin, the operating system takes care of that. So you just simply use stdin.Pablo
I'm trying to make the program work with f whether it is a txt file or stdin so I have to make f point to stdin if no file arg was passed.user8716582
I see what you mean now I don't need to open stdin manually I can just set f = stdin, thank you.user8716582

2 Answers

1
votes

When you start a program, the main() function is not the first thing that get's called, quite a few things happen before the main() function is called. One of those things is to open stdin, stdout and stderr. In general you don't need to worry about the details how the OS does that, you just can relay that when main() is executed, these streams are open and you can use them.

So in your case, you can do this:

#include <stdio.h>

int main(int args, char **argv) {
    FILE *fp;

    if(args == 1) {
        fp = stdin;
    } else {
        fp = fopen(argv[1], "r");

        if(fp == NULL) {
            fprintf(stderr, "Unable to open %s for writing\n", argv[1]);
            return 1;
        }
    }

    // do your read operations on fp

    if(fp != stdin) {
        fclose(fp);
    }

    return 0;
}

So when you call the program without arguments, stdin is used, otherwise a file is used.

The reason why your code crashes is because

f = fopen("stdin", "r");

tries to open a file literally called stdin, which you most probably don't have. fopen will return NULL and you probably don't check for that. If you try to use a function that expects a FILE* pointer but pass NULL, then you'll most likely will get a segfault.

0
votes

USE f = stdin; NOT f = fopen("stdin", "r");