copy text from one file to another - c++

I have tried two different while loops. I think they have a similar problem. Neither of them terminate or give any output.
The task is to copy (byte for byte) one file into another. The file does not have to have endlines, nor does it have to be a .txt file (it could be .exe...).
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
char c, c1, c2;
ifstream inFile;
ofstream outFile;
inFile.open("blackbird.txt");
if (inFile.fail())
{
cout << "\nThe file was not successfully opened for reading."
<< "\nPlease check that the file currently exists.\n\n";
exit(1);
}
cout << "\nThe file has been successfully opened for reading.\n\n";
outFile.open("blackbird_copy.txt");
if (outFile.fail())
{
cout << "The file was not successfully opened for writing" << endl;
exit(1);
}
cout << "The file has been successfully opened for writing.\n\n";
//outFile << "Hello";
// 1) this loop doesn't terminate. 2) the computer doesn't know what c1 is.
/*
while (inFile.get(c1))
{
outFile << c1;
cout << c1;
}
*/
// This one is no better
/*
while (inFile.good())
{
inFile.get(c);
outFile << c;
}
*/
inFile.close();
outFile.close();
// read contents of blackbird_copy to check our work.
inFile.open("blackbird_copy.txt");
while (inFile.get(c2))
{
cout << c2;
}
cout << endl << endl;
return 0;
}

inFile.get(c1) Reads one character and stores it to c1 if available. Otherwise, leaves ch unmodified and sets failbit and eofbit.
You can use inFile.eof() to check whether the end of the file has been reached.

Related

Trying to make something write to a file in c++

I tried programming a file writer, but when i try to write to a file with something that has multiple words it will suddenly create files.
My code
#include <fstream>
#include <iostream>
#include <unistd.h>
int main(int argc, char *argv[]) {
char cwd[256];
while (true) {
getcwd(cwd, 256);
std::string cwd_s = (std::string)cwd;
std::string Input;
std::cout << cwd_s << "> ";
std::cin >> Input;
std::ofstream file(Input);
std::cout << "cmd /";
std::cin >> Input;
file << Input;
};
for (int i; i < argc; i++) {
std::cout << argv[i] << '\n';
};
return 0;
}
I expected to get this:
C:\Users\code> File.txt
cmd /hello world!
File.txt
hello world!
But it only had "hello", it created another file named world!
I have tried changing the code, but to no avail.
So I have wrote this code that I think does what you expect. The behavior you were seing is because you used the same string to store the filename and the user input. Also you redefined a new file every loop (without closing the previous one). I added a signal handler since if you press Ctrl+C the program would quit without saving/closing the file.
I added comments about how you can make a better CLI interface (if you're interested)
#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>
std::ofstream outfile;
void signalHandler(int signum) {
outfile.close();
exit(signum);
}
int main() {
char cwd[256];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
std::cout << cwd << "> ";
} else {
std::cerr << "Error: Could not get current working directory." << std::endl;
return 1;
}
std::string filename;
std::getline(std::cin, filename);
outfile.open(filename);
// We intercept the Ctrl+C signal to close the file before exiting. Else nothing will be written to it.
// You can also use Ctrl+D (EOF: End Of File) to exit the program.
// The best praticte would be to implement a command line interface with a "quit" command. (like a map<string, function> for example)
signal(SIGINT, signalHandler);
// Another good practice is to check if the file did open correctly.
if (!outfile.is_open()) {
std::cerr << "Error: Could not open file for writing." << std::endl;
return 1;
}
std::cout << "cmd / ";
char ch;
while (std::cin.get(ch)) {
outfile.put(ch);
if (ch == '\n') {
std::cout << "cmd / ";
}
}
outfile.close();
return 0;
}
Hope it will help you ! And if you have any question about the code feel free to ask I'll explain !

How do I handle empty files when dumping ifstream to cout?

I'm trying to dump the contents of a file to cout.
#include <iostream>
#include <fstream>
int main(int argc, char** argv)
{
if (argc > 1) {
std::ifstream fin(argv[1]);
if (fin) {
std::cout << "---file contents---\n";
std::cout << fin.rdbuf();
std::cout << "---end contents---\n";
} else {
std::cout << "The file does not exist\n";
}
}
else {
std::cout << "Usage: " << argv[0] << " FILE\n";
}
if (std::cout.good()) {
return 0;
}
else if (std::cout.fail()) {
return 1;
}
else {
return 2;
}
}
This code does not work as intended when the input file is empty. It prints the initial "---file contents---", but never prints the trailing "---end contents---". After debugging, I found the application is not crashing, but instead is putting std::cout in an error state (the return code is 1).
How can I print the contents of an empty file without putting cout in an error state?
This operator<< reference (overload number 10 in the list) explains it all:
If no characters were inserted, executes setstate(failbit).
Since the input file is empty, there's no characters to insert into the output stream. And the failbit is set.
You need to add a specific check for failbit after
std::cout << fin.rdbuf();
to see if the input file was empty or not.

Why is Appended content not showing up on reading from a file in C++?

Please look at this code first, then I will ask my question.
#include <bits/stdc++.h>
#include <fstream>
using std::cout;
using std::cin;
using std::endl;
int main() {
std::ofstream out_file ("outfile.txt"); /* creates a outfile.txt */
if (!out_file) { // checks files existence
std::cerr << "Error bruh!" << endl;
return (1);
}
int num = 100;
double total = 456.78;
std::string name = "atik";
out_file << num << "\n" // writing to the file
<< total << "\n"
<< name << endl;
/* Reading from file, because i want to! - */
std::ifstream in_file("outfile.txt"); // will open outfile for reading.
char c;
while (in_file.get(c)) {
cout << c;
}
/*
Output (as expected) -
100
456.78
atik
Right Now My **output.txt** file is - (as expected)
100
456.78
atik
*/
/* Appending the file that we just created - */
std::ofstream out_file2 ("outfile.txt", std::ios::app);
cout << "\nEnter something to write in file : " << endl;
std::string line;
getline(cin, line);
out_file2 << line; // writes to out_file2
/* Reading from file again - */
std::ifstream in_file2("outfile.txt"); // will open outfile.txt for reading.
if( !in_file2 ) {
std::cerr << "File didn't open. Error encountered." << endl;
}
char ch;
cout << endl;
while( in_file2.get(ch) ) {
cout << ch;
}
/*
Output (unexpected? why?)-
100
456.78
atik
*/
in_file.close();
in_file.close();
out_file.close();
out_file2.close();
return 0;
}
Now, my outfile..txt is - (as expected):
100
456.78
atik
Hello there
Then why is the output for in_file2 not showing Hello there? Why does it truncate the Hello there? Can someone please explain?
out_file2<<line;
doesn't flush (the use of std::endl in the prior code does), so if there's less than a full block of data read from std::cin, the data written to out_file2 is likely stuck in your user-mode buffers (and not visible when you open the file for read independently). Those buffers make I/O efficient by reducing the number of system calls when you're performing many smallish writes, in exchange for any buffered data not being visible outside of that file handle until the buffer is flushed (implicitly by filling, or explicitly by manual flushing or closing the file handle).
Simply changing that line to:
out_file2 << line << std::flush;
(or just .close()ing out_file2 once you're done with it) will cause it to flush properly and you should see the new data on opening it again for read.

How to check if csv file has no data?

I am reading data from a comma delimited csv file. I would like to verify that the file has data before reading and return an error if the file doesn't have any data.
const char* sample_data_file = "sample_data1.csv" ;
std::ifstream file(sample_data_file);
Thanks!
A simple call to stat will tell you if the file is empty. That should be enough to solve your problem.
check the size of the file when you open it?
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
ifstream myfile ("C:/temp/sample1.csv");
// this gives you the number of bytes in the file.
if (myfile.is_open())
{
long begin, end;
begin = myfile.tellg();
myfile.seekg (0, ios::end);
end = myfile.tellg();
if(end-begin == 0)
{
cout << "file is empty \n";
}
else
{
cout << "size: " << (end-begin) << " bytes." << endl;
}
myfile.close();
}
else cout << "Unable to open file \n";
return 0;
}

c++ fstream read() function not working

Why my following code fails to read single integer from file?
It displays "fail() reading" followed by "0".
On linux ubuntu gcc compiler.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream fout2("int_data",ios::binary|ios::out);
int a = 2;
fout2.write((char*)&a,sizeof(a));
int b=0;
ifstream fin2("int_data",ios::binary|ios::in);
fin2.read((char*)&b,sizeof(b));
if(fin2.fail())
cout << "fail() reading" << endl;
cout << b << endl;
}
This could fail for a couple reasons:
Your OS may be protecting you from opening a file that is currently opened for writing
You may not have flushed your data to the file
You can solve both of these by using close before you construct fin2:
ofstream fout2("int_data", ios::binary);
const int a = 2;
fout2.write(reinterpret_cast<const char*>(&a), sizeof(a));
fout2.close();
int b = 0;
ifstream fin2("int_data", ios::binary);
if(!fin2.read(reinterpret_cast<char*>(&b), sizeof(b))) {
cout << "fail() reading" << endl;
}
cout << b << endl;;
Live Example