Thursday, October 9, 2014

Passing Files as Arguments to a C++ Program

When you make a program that has input and output files, you can pass those files into the program immediately when you run the program.

For example, say you have input_file.txt and output_file.txt and program_name.exe all in the same folder, C:\Example_Folder.
You could run your program by opening the command line (on Windows, this is the Command Prompt) and type the following:

cd "C:\Example_Folder" ::In Command Prompt, this brings you into "Example_Folder" where the files are stored
program_name.exe input_file.txt output_file.txt ::This runs "program_name.exe" and passes in "input_file.txt" and "output_file.txt" to the main function as function arguments


In C++ programming, to accept these arguments, the declaration for your main function would look like this:

int main(int argc, char *argv[])


In this, argc is the number of arguments that were passed, in this example, there are three (one for the program file, one for the input file, and one for the output file).
Then argv is a pointer to the the passed in values, so to access the program name, you could use argv[0].
Likewise, to access the input and output files would be to use argv[1] and argv[2], respectively.
However, note that these are still just strings, so argv[1] contains "input_file.txt" and not its contents.
To access the file's contents, use the fstream package by putting the following in the top of your cpp file:

#include <fstream>


Then, where you need to use the files contents, declare a variable as type "ifsteam" (if you're outputting to a file, use "ofstream").
As an example, the following is valid code:

ifstream in;
ofstream out;
in.open(argv[1]);
out.open(argv[2]);


If you need to open the files in different functions other than inside the main function that can be done by declaring the functions as follows:

int main(int argc, char *argv[]);
int read(char *argv[]);
int write(char *argv[]);


In your main function, you would send the files likeso:

read(argv);
write(argv);


A full program that is used to copy the first word of the input file to the output file would be:

#include <string>
#include <fstream>
#include <iostream>

using namespace std;

string read(char *argv[]);
void write(char *argv[], string firstline);
int main(int argc, char *argv[])
{
    string firstline;

    //if there are not 3 arguments passed in from the commandline, return a usage error and exit.
    if ( argc != 3 ) 

    {
        cout << "Usage: program_name.exe input_file output_file" << endl; 
        return -1;
    } 

    firstline = read(argv); 
    write(argv, firstline); 

    return 0; 


string read(char *argv[])

    ifstream in; 
    string firstline; 

    in.open(argv[1]); 

    if ( !(in.is_open()) ) //if it cannot be opened, report an error and exit
    { 
        cout << "Error while opening the input file: " << argv[1] << endl;
        return "There was an error while opening the input file.";
    }

    in >> firstline;

    return firstline;
}

void write(char *argv[], string firstline)
{
    ofstream out;

    out.open(argv[2]);

    if ( !(out.is_open()) ) //if it cannot be opened, report an error and exit
    {
        cout << "Error while opening the output file: " << argv[2] << endl; 

        return
    } 

    out << firstline; 

    return
}


While testing in Microsoft Visual Studio, you can have visual studio automatically send in the commands instead of locating the executable in the project path and running the command prompt from there ("%Project_Path%\Debug\program_name.exe").
To do this, go to the "Project Menu" and select "[Project_Name] Properties" (or press Alt+F7).
In the window that appears, expand "Configuration Properties" and type the input and output file paths into the place for "Command Arguments."
So using the files from this example, you would type:

"C:\Example_Folder\input_file.txt" "C:\Example_Folder\output_file.txt"


Note: The quotes are not necessary for files where the path has no spaces, so I could take the quotes out of my argument paths and be fine.

I hope this helps you with your input and output file needs.  Code on, my friends.

No comments:

Post a Comment

I like feedback, so if you liked what you read or even if you didn't like it, but have some suggestions for me, I'd like to hear them. If you found it boring or found it cool, let me know. If you have a suggestion for something you'd like to see on here, just leave a comment.

You can also email me at michaelzicc44@gmail.com.