user2441391
user2441391

Reputation: 339

Input redirection in C programming?

I am trying to redirect a data file called data1 into my program, but I keep on getting a segmentation fault.

When I try ./w data1 then it reads it correctly but when I do ./w < data1 then the error pops up.

I have to use the second way for my assignment.

Here is what my code looks like:

int main(int argc, char *argv[])
{
 FILE *Q;
 Q = fopen(argv[1],"r");
}

Upvotes: 2

Views: 3425

Answers (7)

ChuckCottrill
ChuckCottrill

Reputation: 4444

Sometimes you want to provide no arguments, and use stdin, sometimes you want to open a file. Here is what you want to do,

int main(int argc, char *argv[])
{
    FILE *Q = stdin; //use stdin unless you provide a filename
    if( (argc>1 ) && strcmp(argv[1],"-") ) { //allow "-" as alias for stdin
        if( !(Q = fopen(argv[1],"r")) ) {
            printf("Error, cannot open %s\n",argv[1]);
            exit(1);
        }
    }
    //read from Q here
}

Upvotes: 0

hyde
hyde

Reputation: 62797

You should initialize your FILE* variable like this:

FILE *Q; 
if (argc >= 2) {
    // at least one argument given, try to open it as file
    Q = fopen(argv[1],"r");
    // let's add error checking while we're at it!
    if (!Q) {
        perror("fopen");
        return 1; // note: this only works if this code is in main function
    }
} else {
    Q = stdin;
}

Now Q is either the file given as command line parameter, or it is stdin, meaning standard input.

Upvotes: 0

zo7
zo7

Reputation: 126

The reason your first command works is because you are providing an argument to your program (in your case, the filename) and your program uses that argument to open the file.

When you are using a redirect, you are redirecting stdin and stdout (which are accessed with functions like gets and printf) to the file, so you don't have to open any files in the program at all.

Upvotes: 2

Jay
Jay

Reputation: 14471

When your program starts with redirection the file is already opened. You can read it from the stream called 'stdin'. You're using a pointer to something that doesn't exist (argv[1]) in that case so that's why it fails.

Many of the C functions default to using stdin so you will not have to specify the file to read from.

Upvotes: 0

Radu Chivu
Radu Chivu

Reputation: 1065

The second command you issue redirects the files' contents to the standard input of your program. This means two things, first of all that you will need to read data from stdin (scanf) and that the argv[1] will be undefined.

So to answer your question, you are trying to open an undefined value which translates to a pointer which in turn causes your crash

Upvotes: 0

Ken Wayne VanderLinde
Ken Wayne VanderLinde

Reputation: 19349

When using ./w < data1, then you don't need to open a file. Just read from stdin.

Upvotes: 2

Piotr Zierhoffer
Piotr Zierhoffer

Reputation: 5151

argv[1] points to the first parameter of your binary (without it's name), so in case of ./w < data1 it is missing. You're trying to access the "illegal" memory, so you get a segfault.

The mark < is a bash feature, it is not passed to C.

If you want to use such a redirection, just read from standard input and don't care about the file/argv. It means "take file data1 and pass it to descriptor 0, that is standard input".

You can use scanf or read(0, ...) to use the file's content.

Upvotes: 3

Related Questions