Copying contents of one file to another leaves the other file empty - c++

I'm trying to copy the contents of document1.txt to document2.txt using this simple program:
int main() {
ifstream in("document1.txt");
ofstream out("document2.txt");
string str;
while(getline(in,str))
out<<str;
}
But, when I run the program, I find that document2.txt is still empty.
What could be wrong?

ifstream in("document1.txt");
ofstream out("document2.txt");
string str;
while(getline(in,str))
{
out<<str;
}
in.close(); // <---
out.close(); // <---
There is a function to close it. Please check this: ifstream and ofstream.

"I have manually created document1.txt and document2.txt"
In case you are running your program directly from Visual Studio, note that the working directory is set to $(ProjectDir) by default, i.e. these files must be placed at the same directory where your project file (.vcproj / .vcxproj) is.
You could either place them to the appropriate directory or specify the full path, for example place them directly to C: and in code do:
ifstream in("C:\\document1.txt");
ofstream out("C:\\document2.txt");
This is something you would notice if you outputted something in case of an error while opening:
if (!out.is_open())
{
std::cout << "ERROR: Can not open document2.txt" << std::endl;
return -1;
}
Note that in this case you don't actually need to flush any buffer, neither close the streams explicitly. All of this will happen automatically when these objects are destructed, i.e. when the execution goes out of scope.

ifstream document1("document1.txt");
ofstream document2("document2.txt");
string str;
getline(document1, str);
document2<< str<< endl;
document1.close();
document2.close();
Try this code. It works for me.

test.cpp
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream in("document1.txt");
ofstream out("document2.txt");
string str;
while(getline(in,str))
out<<str<<endl;
}
document1.txt
aaaaaaaa
bbb bbb
c c c c
d
under command line you can do
$g++ test.cpp -o test.out
$test.out
And then you will get document2.txt
aaaaaaaa
bbb bbb
c c c c
d
P.S. All the code tested under Mac and Linux
P.S. if you change 9th line of test.cpp from out<<str<<endl; to out<<str;
document2.txt would becomes
aaaaaaaabbb bbbc c c cd
because the getline(in,str) function would extracts characters from in and stores them into str until '\n' or end-of-file is found.
Which means str does not contains '\n'. You need to add '\n' by yourself.
P.S. under C++, as LihO says, you don't need to close in and out, since in and out would be closed at line 10 }
Also, you don't need to flush when you execute line 9, since endl has flush function.

Related

Unable to open file.txt with c++

I've looked up similar posts here, but none seem to be doing the job for my question. I'm basically trying take a sequence of words in a .txt file and put each word in a vector, and printing each value afterwards. For example, we have I love racing cars in array.txt, and I want my vector to have "I" at position 0, "love" at 1 and so on. Unfortunately, the code does not access "array.txt", so it never executes the code in the if condition.
Now I've heard that by using the fstream library it should work just fine, but the file is never found. I suspect that it doesn't work because it cannot find the path, but I have never opened files in C++. Also, I have not put my file anywhere in my project folder.
Some changes I've already tried:
file.open("array.txt");
omitting file.close();
include "C:\array.txt"; (with the # in front)
file.open("C:\array.txt")
And I'm using Windows 10, if this matters.
#include <iostream>;
#include <string>;
#include <vector>;
#include <fstream>;
//#include <"C:\Users\Samer El-Hage\Documents">;
using namespace std;
void main(){
vector<string> v (10);
ifstream file;
file.open("C:\array.txt", ios::in);
if (file.is_open())
{
for (int i = 0; i < 3; i++)
{
file >> v[i];
}
file.close();
}
else cout << "Could not access file.";
for (int i = 0; i < 3; i++)
{
cout << v[i] << " ";
}
}
This code prints "Could not access file."
The file cannot be opened because the file system can't find the file named "[Bell]rray.txt". the character sequence '\a' is the "Make my computer Beep" character.
Use either forward slashes: "C:/array.txt", an escaped backslash: "C:\\array.txt" or a raw string literal: R"(C:\array.txt)"
The file must also exist at the specified location. If you do not provide a drive and just say "array.txt" the location defaults to wherever the executable is (or in an IDE, the Working Directory).
Also, you have unnecessary semi-colons after your includes. (In fact, in a Treat Warnings as Errors setup, this won't compile!)
I got it! I had not put the .txt file in my folder with the source code, which, strangely enough, was not mentioned in my previous search results... I got to search better!
\a simply turns the computer beep on. Try writing "C:\\array.txt" instead in the open call.
Try not calling open explicitly:
ifstream file ("array.txt");
Look at the examples here:1

Input Output with fstream

Can anyone tell me what is wrong with this code? I always get not open.
#include <iostream>
#include <fstream>
using namespace std;
int main(){
fstream fs;
fs.open("fsfile2",ios::in|ios::out|ios::binary);
if(fs.is_open()){
fs.write("wow",sizeof("wow"));
char str[20];
fs.read((char*)str,sizeof(str));
cout<<str<<endl;}
else
cout<<"Not open\n";
return 0;
}
Try this code
fs.open("fsfile2", ios::app|ios::in|ios::out|ios::binary);
By using the open() like you are that file will not be created if that is your goal.
If you want to create a new file please look at: fstream won't create a file
If the file exists, you are not looking for it in the right path. Or change the file name to the full path or put the executable in the folder where the file is.
Hope this helps.
Probably, you do not have permissions to create files in the directory, where your executable is.
Solution:
Please add a file extension to the filename.
If it's a text file, it will be
"fsfile2.txt"
Then, I tried removing
ios::in
since the first process only writes to file, and by removing that, the file is created and "wow" is also written at it.
In order for these lines
fs.read((char*)str,sizeof(str));
cout<<str<<endl;
to work,
You need to close the stream after writing to it, then open the stream in read mode, then read the contents. Take note that closing the stream will save the edited file.
Additional:
You can also change
fs.write("wow",sizeof("wow"));
to
fs << "wow";
You can do the same when reading from file,
fs >> str;
You can also use the string class of C++, instead of char array so that the number of characters inside the file won't be your problem anymore.
#include <string>
string str;
Checking for EOF (end-of-file) is recommended since files are read line by line. Once you add a new line and add a character to the line, the code that doesn't loop until EOF will only read the first line of the file.
In order to solve this, it is recommended to loop until EOF is reached.
while(!fs.eof()) {
fs >> str;
cout << str << endl;
}
So here is the improved snippet:
#include <string>
fs.open("fsfile2.txt", ios::out); // ios::out for write only
if(fs.is_open()) {
// writes "wow" to file
fs << "wow";
// closes the file
fs.close();
// ios::in for read only
fs.open("fsfile2.txt", ios::in);
// better to define variable just before using it
string str;
// loops until end-of-file
while(!fs.eof()) {
// reads a line from file, stores it to str
fs >> str;
// shows str to screen
cout << str << endl;
}
}
*Note: I removed
ios::binary
Since your code is not dealing with binary files yet.
I tried these and it worked fine! Have a nice day!
fstream fs; does not create a new file for you.
You need to make sure that the file exists in your project directory.
On the other hand, if you were to use ofstream fs("file.txt"); it would create the file for you. Or use only ios::out when you open fstream fs, this will create the file for you.

read and write a binary file in c++ with fstream

I'm trying to write simple c++ code to read and write a file.
The problem is my output file is smaller than the original file, and I'm stuck finding the cause.
I have a image with 6.6 kb and my output image is about 6.4 kb
#include <iostream>
#include <fstream>
using namespace std;
ofstream myOutpue;
ifstream mySource;
int main()
{
mySource.open("im1.jpg", ios_base::binary);
myOutpue.open("im2.jpg", ios_base::out);
char buffer;
if (mySource.is_open())
{
while (!mySource.eof())
{
mySource >> buffer;
myOutpue << buffer;
}
}
mySource.close();
myOutpue.close();
return 1;
}
Why not just:
#include <fstream>
int main()
{
std::ifstream mySource("im1.jpg", std::ios::binary);
std::ofstream myOutpue("im2.jpg", std::ios::binary);
myOutpue << mySource.rdbuf();
}
Or, less chattily:
int main()
{
std::ofstream("im2.jpg", std::ios::binary)
<< std::ifstream("im1.jpg", std::ios::binary).rdbuf();
}
Two things: You forget to open the output in binary mode, and you can't use the input/output operator >> and << for binary data, except if you use the output operator to write the input-streams basic_streambuf (which you can get using rdbuf).
For input use read and for output use write.
There are 3 problems in your code:
1- You have not opened your output file in Binary.
2- Your code return "1", normally you should return "0", if something went wrong then return an error code.
3- You should use "manipulators" and make c++ not to avoid whitespaces, so in order to read from file instead of:
mySource >> buffer;
you should use:
mySource >> std:noskipws >> buffer;
Well, its just because of padding at the end of the image. eof of any file do not include the padded bytes added at the end of file.
Try this
take img1.jpg contains 20 space charecter at the end not visible here (uegfuyregwfyugwrerycgerfcg6ygerbucykgeugcrgfrgeyf ) and run your program (do not include parenthesis in the file, these are used to show the data content)
you will see img2.jpg contains (uegfuyregwfyugwrerycgerfcg6ygerbucykgeugcrgfrgeyf)
So, its better option to read the file byte by byte using the filesize which you can get using stat, and run for loop till filesize. Hope this should resolve your problem you mentioned above

Reading File in C++

I am unable to figure out why my code is not able to open and read a file. What am i missing?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char * const argv[])
{
string line;
ifstream myfile ("input_file_1.txt");
if (myfile.is_open())
{
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
}
else
{
cout << "Was unable to open the file" << endl;
}
return 0;
}
The file "input_file_1.txt" is int he same directory as my .cpp file and it has read permissions. I even gave gave it 777 permissions and i was unable to read it.
Can anyone tell me what i am doing wrong? I really cannot figure it out....
Try to use full path for the file
The default location to look for the file is where the executable is , not where the source is.
How and where do you execute your program? From a IDE?
Can you run the program from the same directory where you have your text file.
Another possibility is to use an absolute path to the file.
If you don't specify a path, the library will attempt to load the file from the current directory. You need to make sure that this is where the file is.
Also, you might not be able to open the file if it is opened in an exclusive manner by another program. Ensure that it is not still open in another program such as your editor.
Other Problems:
Explicitly testing for EOF is usually wrong.
The last valid read (getline() here) reads up-to but no past the EOF. You then print the line. Then restart the loop. These test for eof() does not fail (as it has not read past the EOF). You then enter the loop body and attempt to read the next line (with getline()) this fails as there are 0 bytes left to read (thus leaving the value of line in an undefined state). You then print out line (undefined value) and a newline character.
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
A correct version of a loop reading a file is:
while (getline (myfile,line))
{
cout << line << endl;
}
This works because the getline() returns a reference to a stream. A stream used in a boolean context (like a while condition) tests to see if the stream is in a bad state (ie it test for EOF and other bad situations) and returns an object that can be used correctyl in the context. If the state of the stream is OK then a successful read has happened and the loop is entered (thus allowing you to print the line).
The binary created from your code (including your cpp) is executed somewhere different from your code is, probably a "bin"-folder. You schould put the file into the same folder as your executable.

getline() returns empty line in Eclipse but working properly in Dev C++

Here is my code:
#include <iostream>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main() {
string line;
ifstream inputFile;
inputFile.open("input.txt");
do {
getline(inputFile, line);
cout << line << endl;
} while (line != "0");
return 0;
}
input.txt content:
5 9 2 9 3
8 2 8 2 1
0
In Enclipse, it goes to infinite-loop. I'm using MinGW 5.1.6 + Eclipse CDT.
I tried many things but I couldn't find the problem.
Since you are on windows try:
} while (line != "0\r");
The last line is stored as "0\r\n". The \n is used as the line delimiter by getline so the actual line read will be "0\r"
or
you can convert the dos format file to UNIX format using command
dos2unix input.txt
Now your original program should work. The command will change the \r\n at the end of the line to \n
Also you should always do error checking after you try to open a file, something like:
inputFile.open("input.txt");
if(! inputFile.is_open()) {
cerr<< "Error opening file";
exit(1);
}
It will create an infinite loop if no line contains exactly 0. For example 0\n is not the same thing as 0. My guess is that that is your problem.
EDIT: To elaborate, getline should be discarding the newline. Perhaps the newline encoding of your file wrong (i.e. windows vs. unix).
Your main problem is working directory.
Because you are specifying a file using a relative path it searches for the file from the current working directory. The working directory can be specified by your dev environment. (Note: The working directory is not necessarily the same directory where the executable lives (this is a common assumption among beginners but only holds in very special circumstances)).
Though you have a special end of input marker "0" you should also check that the getline() is not failing (as it could error out for other reasons (including beady formatted input). As such it is usually best to check the condition of the file as you read it.
int main()
{
string line;
ifstream inputFile;
inputFile.open("input.txt");
while((getline(inputfile, line)) && (line != "0"))
{
// loop only entered if getline() worked and line !="0"
// In the original an infinite loop is entered when bad input results in EOF being hit.
cout << line << endl;
}
if (inputfile)
{
cout << line << endl; // If you really really really want to print the "0"
// Personally I think doing anything with the termination
// sequence is a mistake but added here to satisfy comments.
}
return 0;
}