2

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");
}

7 Answers 7

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

2

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

Comments

0

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

Comments

0

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.

Comments

0

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.

Comments

0

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
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.