I want to get the input file name in advance, when my program is called, not have my program ask the user for the filename.
I've seen many examples where the program will ask the user for input like:
int main()
{
cout << "Enter file name: ";
cin.get();
//run program
return 0;
}
However, there are not many examples shown where the input is stated in the command line when the program is called:
int main(int argv, char* argc[])
{
ifstream inputfile;
inputfile.open(argc);
//run program
return 0;
}
In other words, the user would type something like this on the terminal:
$./program example.txt
Sorry if my question is like an ELI5 submission.
I think you guys might get the gist of what I am trying to do.
Use:
int main(int argc, char* argv[])
{
ifstream inputfile;
if(argc == 2)
inputfile.open(argv[1]);
else
cout<<"Please nenter filename as command line argument!\n";
//run program
return 0;
}
Here, argc and argv are called command line arguments.
The value of argc is equal to the number of command line arguments, which includes the filename of the executable file itself.
argv is an array of strings passed as command line arguments, where the name of the executable file is at argv[0] and the rest of the arguments follow that.
You need to use:
inputfile.open(argv[1]);
However, I suggest adding checks to the program.
int main(int argc, char* argv[]){
if ( argc < 2 )
{
cerr << "Not enough arguments.\n";
return EXIT_FAILURE;
}
// There is an argument. Use it.
ifstream inputfile;
inputfile.open(argv[1]);
//run program
return 0;
}
Related
I want to read a file and count the words. I want it set up so I can use a command line or, if no file is entered on the command line, to trigger an if statement that will get the file name and read it, then count the words. It works if I type the file name in command line, however it seg faults if I don't use it. Here is the code:
int main(int argc, char **argv)
{
char file[75];
if (argc < 2)
{
cout << "Please enter the filename: ";
cin >> file;
strcpy(argv[1], file);
}
string content;
ifstream inFile(argv[1]);
int count = 0;
while (inFile >> content)
count++;
inFile.close();
display(count, argv);
return 0;
}
You should not modify data of argv especially out of bounds. You logic should work opposite:
char file[75];
if (argc < 2)
{
cout << "Please enter the filename: ";
cin >> file;
} else
strcpy( file, argv[1] );
string content;
ifstream inFile(file);
but you better use std::string for variable file as well.
Also cin >> inputs only words (excluding space symbols) but filenames can have them, so you better use cin.getline( file ) or std::getline( cin, file ) if you change file to std::string
If the condition is true that is if argc is indeed less than 2 then in general case argc is equal to 1 and according to the C Standard argv[argc] is equal to NULL.
So the program in this case has undefined behavior.
In any case it is a bad idea to copy a string to argv[n] where n is some index because the source string can be larger than the target string.
You could use a reverse approach that is to copy argv[1] to file.
I'm fairly new to C++, I'm trying to figure out how to take in arguments from a text file and use them in my program.
So if I wanted to include a text file whatever.txt in a command, it would use specified lines as arguments.
Like if the text file looked like this:
1 2
and I wanted to use 1 and 2 from it, as arguments in my program.
So far from what I've gathered, I need something akin to this:
int main (int argc, char const *argv[]) {
to start, but not sure where to go from here.
I'm trying to mess around with certain stuff, but I'm still pretty new and outside of loops and things I can't do much with the language yet!
Short of giving you the code that will do this for you (which would ruin the fun of learning how to do these things), the steps I would follow would be:
Take one argument from the command line as the file name you want to read the information from. Think of running your script like this:
$ ./myscript whatever.txt
Then, argv[0]="./myscript" and argv[1]="whatever.txt".
Open the file (perhaps ifstream would be good for this).
Loop through each line of the file (maybe using getline to put each line into a string)
Parse each line of the file (I've seen stringstream used for filling variables from a string).
Hopefully that will help you along your way.
int main(int argc, char *argv[])
after retrieving files names in the main function you should open each file and retrieve its contents
Sample code
int main(int argc, char* argv[])
{
for(int i=1; i <= argc; i++) // i=1, assuming files arguments are right after the executable
{
string fn = argv[i]; //filename
cout << fn;
fstream f;
f.open(fn);
//your logic here
f.close();
}
return 0;
}
https://stackoverflow.com/a/30141375/3323444
argc is the number of arguments passed in to your program, argv is an array of character strings holding the names of arguments passed in.
at least there's one parameter passed in which is argv[0] which is name of program.
after building this code run it form a command prompt as:
main.exe data.txt
or simply DRAG AND DROP file "data.txt" on your main.exe
main.exe is your program, data.txt is text file containing data you want to use
#include<iostream>
#include<fstream>
int main(int argc, char* argv[])
{
char c;
if(argc < 2)
{
std::cout << "No file passed to program!" << std::endl;
return 1;
}
std::ifstream in (argv[1] , std::ios::in);
if(!in)
std::cout << "Unable to read file: " << argv[1] << std::endl;
while(in >> c)
std::cout << c << std::endl;
in.close();
std::cin.get();
std::cout << std::endl;
return 0;
}
At the start of my program, it should get path to the input file and path to the output file from the console.
But if user give not required number of parameters or wrong parameters (with spaces for example, or without ".txt") it should give the user second chance to enter those parameters without exiting the program. Is it possible?
int main(int argc, char* argv[])
{ //and here should be something to check if the user entered parameters correctly
//(number and if they look like a path) and give a user another try if this is wrong
//(so that user enter them from console again)
string path_open(argv[1]);
strin path_out(argv[2]);
Yes it's possible, but... weird. If you are going to have your program ask for input, why not just put that in a loop until you get proper input? Ultimately, I'd do one or the other:
Get command line input (and, as #IInspectable suggests in the comments, if it's not valid, exit the program); OR
Have program ask for input recursively until the user gives valid input.
Input from command line:
int main(int argc, char* argv[])
{
// sanity check to see if the right amount of arguments were provided:
if (argc < 3)
return 1;
// process arguments:
if (!path_open(argv[1]))
return 1;
if (!path_out(argv[2]))
return 1;
}
bool path_open(const std::string& path)
{
// verify path is correct...
}
Program asks for input:
int main()
{
std::string inputPath, outputPath;
do
{
std::cout << "Insert input path: ";
std::getline(std::cin, inputPath);
std::cout << std::endl;
std::cout << "Insert output path ";
std::getline(std::cin, outputPath);
} while (!(path_open(inputPath) && path_out(outputPath)));
}
Of course you'd validate input separately in case they were entering a valid input path but invalid output path, but you get the gist.
I am new to using the command line to start up a program. I want to call my file, called "file.txt". I've been searching for examples but I have not seen what the command line writes.
int main(int argc, char *argv[])
{
if (argc < 2) {
cerr << "Error: file name argument not given" << endl;
exit(1);
}
ifstream inFile( argv[1], ios::in);
}
Got it. So through the command line I navigate to my .exe and call the file I want after.
C:\Users\me\sampleProject\bin\Debug>test.exe sampleFile.txt
And it works.
Thanks.
I posted a similar code earlier, but I think this is a different issue now. I just can't figure out why my run code won't go past "infile open". ("-e" prints out, "-d" doesn't) I'm trying to open my file, use a command line option to determine if I will print out a certain multiple of characters.
For example, a.out -d 2 < sample.txt will print out every second letter.
int main (int argc, char *argv[])
{
ifstream infile;
if (infile.good())
printf("infile open \n");
int c;
int number = 0;
int count = 0;
string str1 = argv[1];
string str2 = "-d";
string str3 = "-e";
if (str1.compare(str2) == 0)
{
printf("entered -d\n");
c = infile.get();
while(!infile.eof()) {
number = atoi(argv[2]);
if (count == number)
{
cout.put(c);
count = 0;
}
else
count++;
c = infile.get();
}//end while
}//end if
if (str1.compare(str3) == 0)
printf("entered -e\n");
}//end main
infile is never opened:
ifstream infile; // Does not open a file as no file name is supplied.
Either use cin or pass "sample.txt" as another command-line argument and open it:
ifstream inFile(argv[3]);
if (inFile.is_open())
{
}
Other points:
Use std::cout instead of mixing printf() and std::cout.
atoi() returns 0 if the argument is invalid or if the argument is a valid 0. See strtol() for an alternative.
There is no reason to convert argv[2] on every iteration of the while. Just do it once prior the while.
Always check argc before accessing the elements of argv, to avoid invalid memory access.
std::string instances can be compared using operator==.
When running something like this on command line: "a.out < sample.txt", there is no actual filename specified to open, the "<" command in Unix will just make the contents of sample.txt be passed to a.out via standard input...therefore, like hmjd pointed out, you should use cin. You would want to physically open a file if it was supplied as an argument, i.e. "a.out sample.txt" as opposed to "a.out < sample.txt".