Martin
Martin

Reputation: 1090

fopen() and command line arguments

I'm trying to write a program that will read the first character in a text file. If I use ./a.out myfile.txt it works as intended but if I use ./a.out <myfile.txt I get Segmentation fault: 11. The reason why I'm trying to include the <is because this what is in the spec of the assignment. The below code is just a simplified example that i've made that has the same issue:

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


int func(int argc, char **argv){
    FILE *fp;
    int test = 0;
    fp = fopen(argv[1], "r");
    fscanf(fp, "%i", &test);
    printf( "current file: %s \n", argv[1]);


}


int main(int argc, char **argv){
    func(argc, argv);   
}

Is there any way I can get it to accept the argument as <myfile.txt?

Upvotes: 4

Views: 6127

Answers (3)

demi
demi

Reputation: 5504

In your command ./a.out <myfile you redirect stdin to myfile. This means reading from stdin is actually reading from myfile. So, in this case your argc == 1, so argv[1] you use to open is NULL (see main spec on its arguments). fopen crashes when uses NULL name.

You may do your utility in another way: always read stdin. When you need file to input do like this: cat myfile | ./a.out. This is very nice approach and worth considering.

Upvotes: 2

Eric
Eric

Reputation: 843

If you want to use a file if specified, but otherwise stdin, use something like:

if (argc > 1)
    fp = fopen(argv[1], "r");
else
    fp = stdin;

Upvotes: 5

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799470

No, nor should you try. Files redirected this way will appear at stdin and you should use that instead (hint: check argc).

Upvotes: 7

Related Questions