Reputation: 25
I have a problem with I/O streams in C++. I have to write a program which reads data from a file and writes to another file. The command in CMD should be like:
program < file1 > file2
The names of the files should be provided by the user (could be random).
I've written some code, but it's not correct. I don't know how to redirect the stream to a file using the command > file2
.
What can I change in my code to make it work? Can somebody help me?
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string input_line;
while (std::getline(std::cin, input_line)) {
std::ofstream output_file("file2.txt", std::ios::app);
if (!output_file.is_open()) {
std::cerr << "Error" << std::endl;
return 1;
}
output_file << input_line << std::endl;
output_file.close();
}
return 0;
}
Upvotes: 1
Views: 358
Reputation: 13076
Files are just streams, so implement a copy function in terms of std::istream&
and std::ostream&
. This allows you to avoid file (location) problems during testing, use a std::istringstream
for testing (instead of std::ifstream
). And similar instead of std::ofstream
you can use std::cout
as output.
Also, learn to write functions with readable names.
It will become something like this:
#include <sstream>
std::istringstream input_file
{
"Line 1 : One\n"
"Line 2 : Two\n"
"Line 3 : Three\n"
"Line 4 : Four\n"
};
void copy(std::istream& is, std::ostream& os)
{
std::string line;
while (std::getline(is, line)) os << line << "\n";
}
int main()
{
copy(input_file, std::cout);
}
Upvotes: 0
Reputation: 6685
If you want to dictate the filenames from the command line then you don't really need the '<' and '>' redirectors. You could just state the names of the files and use the int main( int argc, char * argv[] )
form of program.
Thus:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main( int argc, char * argv[] )
{
if ( argc != 3 )
{
cerr << "Correct usage is myprog.exe infile outfile";
return 1;
}
ifstream in( argv[1] );
if ( !in )
{
cerr << "Input file not found";
return 1;
}
ofstream out( argv[2] );
for ( string line; getline( in, line); ) out << line << '\n';
}
Upvotes: 0
Reputation: 264631
I have a problem with I/O streams in c++.
OK.
Command in CMD should be like: "program < file1 > file2"
This implies you are using the shell to do the work. Here. The <
and >
are shell "operators" to redirect files to standard in and standard out of the program. This means your program should read from std::cin
and write to std::cout
.
You assume the output file is "file2.txt"!
std::ofstream output_file("file2.txt", std::ios::app);
You are always appending to it. If the file already exists, this may not be what you want, as it will add the new content onto any old content. I would probably change that (if I was using files). But the simpler solution is to use std::cout
(as indicated above).
I am assuming you are doing this as part of an exercise, so going through the steps.
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::string input_line;
while (std::getline(std::cin, input_line)) {
// This should open file is inside the loop.
// You should probably move it outside the loop.
// A side effects of this is that you don't need to append
// so you will destroy the old content and get rid of it.
std::ofstream output_file("file2.txt", std::ios::app);
if (!output_file.is_open()) {
std::cerr << "Error" << std::endl;
return 1;
}
// probably don't want to use `std::endl` here.
// This forces a flush from the internal buffer to the hardware.
// You probably just want to use `"\n"` here.
output_file << input_line << std::endl;
// You are closing the output file after writting one line to it.
// May be more effecient to only close the file after writting
// all the lines to the file.
output_file.close();
}
return 0;
}
If I was writing this for a class that was trying to understand streams. This is how I would re-write more like this:
#include <iostream>
#include <string>
int main()
{
std::string input_line;
// Use a while loop to read a line from the input.
while (std::getline(std::cin, input_line)) {
// If the read worked the we write line back to the
// output.
std::cout << input_line << "\n";
}
// When the read (std::getline()) fails the loop
// will not be entered. So you can stop the loop
// and end up here.
// Optional return at the end of main.
return 0;
}
Note: This is not quite perfect as the last line may not include a new line character, but the code above always add a newline to every line. I leave it as an exercise for you to solve this last simple issue.
Upvotes: 3