Search code examples
c++file-ioerror-handlingcommand-line-argumentsifstream

C++ input redirection causing error while file arguments work


When I specify an input file as a file argument, like so:

./asm ex1_in

everything works as it should!

However, when I specify an input file using redirection, like so:

./asm < ex1_in

the program throws the error it is supposed to throw when the input file is corrupt or doesn't exist.

This is the part of the code that handles input and file arguments:

int main(int argc, char * argv []) {
    ifstream InFile(argv[1], ios::in); 

    if (!(InFile.is_open())) {  /* check file */
        fprintf (stderr, "The input file cannot be open or cannot be read. \n");
        return 2;
    }                

    if (InFile.is_open()) {
        //some stuff
        InFile.close();     
    }   

    //other stuff
}

I would like to be able to keep using ifstream, as it is very helpful for the rest of the program.

Also, the program is supposed to accept input directly on stdin if no file argument is supplied. Currently, if no file arguments are supplied, it throws the same error, instead of looking for user input.

EDIT: I added a line in main to try to see what's going on, and it looks like when input redirection is used, the program doesn't see argv[1] or anything after it.

cout << argv[0] << " " << argv[1] << " " << argv[2];

prints out only ./asm.

When input redirection isn't used, it prints out:

./asm ex1_in my1_out

Solution

  • You are trying to open argv[1] as a file every time you run the program.

    In the first case, argv has a lenght of two (the executable name and the filename) so it opens and does what it needs to do normally, but when you run it redirecting the file to the stdin, argv just contains the executable name, and since argv[1] is a C-style string, it will read everything until it finds a null byte, then pass whatever it read to the std::ifstream constructor, failing each time.

    You should use argc to know the number of arguments passed, and use either the file or stdin depending on the number of arguments.