I open a file using ,
std::ifstream ifs(filename);
I want to open a new file using same ifs variable , how do i do that ?
ifs.close();
ifs.open(newfilename);
Please take into consideration that std::ifstream.close() does not clear its flags,
that may contain values from the last session. Always clear the flags with the clear() function before using the stream with another file.
Example:
ifstream mystream;
mystream.open("myfile");
while(mystream.good())
{
// read the file content until EOF
}
mystream.clear(); // if you do not do it the EOF flag remains switched on!
mystream.close();
mystream.open("my_another_file");
while(mystream.good()) // if not cleared, this loop will not start!
{
// read the file
}
mystream.close();
ifs.close(); //close the previous file that was open
ifs.open("NewFile.txt", std::ios::in); //opens the new file in read-only mode
if(!ifs) //checks to see if the file was successfully opened
{
std::cout<<"Unable to read file...\n";
return;
}
char* word = new char[SIZE]; //allocate whatever size you want to
while(ifs>>word)
{
//do whatever
}
ifs.close(); //close the new file
delete[] word; //free the allocated memory
Related
ifstream myfile;
myfile.open("FileTest");
string line;
if(myfile.is_open())
{
cout<<"Reading from file...";
getline(myfile,line);
}
if(myfile.fail())
{
cout<<"Unable to open file"<<endl;
}
myfile.close();
C++ tries to open the file in the current directory with the exact name FileTest. Check to see if the file is in the current directory? Maybe you spelled the name incorrectly? Maybe you forgot to write FileTest.txt? You are using ifstream, which will fail if the file you're trying to open does not exist or is corrupted.
first time here. I am a student doing some c++ coding for end year project. The programme that I coded does not read the text file even though everything seems to be in order. Some helps would be fantastic!
void transactionRecords(double total, char answer, string nameT, int HpNo, string address)
{
fstream myFile;
string name;
char idStatus;
double amt, sumAll=0;
myFile.open("transaction.txt",fstream::in);
if (!myFile) cout<<"Unable to Open File under Input Mode";
else
{
while (!myFile.eof())
{
myFile>>name>>idStatus>>address>>HpNo>>amt;
if (myFile.fail()) break;
}
myFile.close();
myFile.open("transaction.txt",fstream::app);
if (!myFile) cout<<"Unable to Open File under App Mode";
else
{
myFile<<nameT<<" "<<answer<<" "<<address<<" "<<HpNo<<" "<<total<<endl;
if (myFile.fail()) cout<<"Error encountered while adding data!\n";
}
}
myFile.close();
}
this is whats in the text file
Johns Y pasir_ris 81231211 4.14
First, I suggest you use the RAII principle when creating files that is:
void myfunction() {
ifstream f{"file.txt"};
// your logic here
// NB -- no need to manually close file, prevents resource leaks
}
There is no need to manually close or open such a file, it is opened by the constructor and closed when the destructor is invoked upon exiting the current scope. This prevents leaks of file handles and is a pervasive technique in C++.
Second, use the standard stream read loop in C++:
while (myFile>>name>>idStatus>>address>>HpNo>>amt) {
// your logic here, the read has succeded
// TODO process myFile, name, idStatus etc.
}
With these changes, your example should look something like:
void transactionRecords(double total, char answer, string nameT, int HpNo, string address)
{
ifstream myFile{"transaction.txt"};
string name;
char idStatus;
double amt, sumAll=0;
if (!myFile) cout<<"Unable to Open File under Input Mode";
return;
while (myFile>>name>>idStatus>>address>>HpNo>>amt) {
// TODO do something here??
}
ofstream tFile{"transaction.txt"};
if (!myFile) cout<<"Unable to Open File under App Mode";
return;
if (!(tFile<<nameT<<" "<<answer<<" "<<address<<" "<<HpNo<<" "<<total<<endl)) {
cout<<"Error encountered while adding data!\n";
}
}
}
You should probably do something in the TODO block, currently you are only storing the last values read? If you only mean to process one line from the file, swap the while loop with an if.
I am trying to split a large data file into several small text files. The following code opens and closes a new file every time, which is not feasible. Is there an alternative way of doing this?
ifstream infile(file_name);
if(infile)
{
char val;
while(!infile.eof())
{
ofstream ofile (ofile_name);
infile >> val;
ofile << val;
if( infile.peek() == '\n' )// last entry on the line has been read
{
row_counter++;
if (row_counter == win_size)
// generate new ofile_name
}
ofile.close();
}
infile.close();
}
You will not be able to create several output files without opening and closing the output files.
The reason is, that each output file should have a unique name. You will have to generate useful names for the output files. The connection between the file (content) and the file name will be done in the open call (or ofstream constructor).
Edit
To avoid open and close for each character you need status variable. In your example row_counter is usable for it. You need following steps:
open initial ofile before your while(!infile.eof()) loop
close your ofile, generate next name and open the new where where you wrote // generate new ofile_name
finally close your ofile after the loop.
This could be done in this way:
if(infile)
{
char val;
row_counter = 0;
ofstream ofile (ofile_name);
while(!infile.eof())
{
infile >> val;
ofile << val;
if( infile.peek() == '\n' )// last entry on the line has been read
{
row_counter++;
if (row_counter == win_size)
{
row_counter = 0;
ofile.close();
// generate new ofile_name
ofile.open(ofile_name); // you might change the nMode parameter if necessary
}
}
}
ofile.close();
infile.close();
}
I need to split a file into multiple files without compression. I found this on cpp reference
#include <fstream>
using namespace std;
int main () {
char * buffer;
long size;
ifstream infile ("test.txt",ifstream::binary);
ofstream outfile ("new.txt",ofstream::binary);
// get size of file
infile.seekg(0,ifstream::end);
size=infile.tellg();
infile.seekg(0);
// allocate memory for file content
buffer = new char [size];
// read content of infile
infile.read (buffer,size);
// write to outfile
outfile.write (buffer,size);
// release dynamically-allocated memory
delete[] buffer;
outfile.close();
infile.close();
return 0;
}
and I thought to do it like this. But the problem is ..I can create only the 1st file because I can read data only from the beginning of the file. Can it be done like this and if no..what is the best way to split these files.
The example code doesn't split a file into multiple files; it just
copies the file. To split a file into multiple files, just don't close
the input. In pseudo-code:
open input
decide size of each block
read first block
while block is not empty (read succeeded):
open new output file
write block
close output file
read another block
The important part is not closing the input file, so that each read
picks up exactly where the preceding read ended.
You can seek the stream to the desired position and then read stream. Check this piece of code.
// get size of file
infile.seekg(0,ifstream::end);
size=infile.tellg();
infile.seekg(0);
All you need to do is to remember the position where you stopped reading infile, close outfile, open new outfile, reallocate buffers and read infile to buffer and write to second outfile.
You can read data from anywhere in the file - you already moved to the end and back to the start successfully.
You don't need to though: just write a loop to sequentially read each outputSize and write it to a new file, for some outputSize < size.
Why reinvent the wheel - Try split
Even has the source code for you to get ideas if you want to implement it in C++
I think I have got a solution to your problem...
You read all the first file in a char array.
Then you write the first half of your array in a file, and then second half of you array in other file...
For example :
#include <fstream>
using namespace std;
int main () {
char * buffer;
long size;
ifstream infile ("test.txt",ifstream::binary);
ofstream outfile ("new.txt",ofstream::binary);
ofstream outfile2 ("new2.txt",ofstream::binary);
// get size of file
infile.seekg(0,ifstream::end);
size=infile.tellg();
infile.seekg(0);
// allocate memory for file content
buffer = new char [size];
// read content of infile
infile.read (buffer,size);
// write to outfile
outfile.write (buffer,size/2);
outfile2.write (buffer+size/2,size);
// release dynamically-allocated memory
delete[] buffer;
outfile.close();
infile.close();
outfile2.close();
return 0;
}
You can also read the first half, write it, then read the second half and write it... Just have a look to that :
int main () {
char * buffer;
long size;
long halfSize;
ifstream infile ("test.txt",ifstream::binary);
ofstream outfile ("new.txt",ofstream::binary);
ofstream outfile2 ("new2.txt",ofstream::binary);
// get size of file
infile.seekg(0,ifstream::end);
size=infile.tellg();
infile.seekg(0);
halfSize = static_cast<int>(floor(size/2));
// allocate memory for file content
buffer1 = new char[halfSize];
buffer2 = new char[size-halfSize];
// read content of infile
infile.read (buffer1,halfSize);
infile.read (buffer2,size-halfSize);
// write to outfile
outfile.write (buffer1,halfSize);
outfile2.write (buffer2,size-halfSize);
// release dynamically-allocated memory
delete[] buffer;
delete[] buffer2;
outfile.close();
infile.close();
outfile2.close();
return 0;
}
This is the code I have, but the file is a little smaller and doesn't execute:
int WriteFileContentsToNewFile(string inFilename, string outFilename)
{
ifstream infile(inFilename.c_str(), ios::binary);
ofstream outfile(outFilename.c_str(), ios::binary);
string line;
// Initial read
infile >> line;
outfile << line;
// Read the rest
while( infile )
{
infile >> line;
outfile << line;
}
infile.close();
outfile.close();
return 0;
}
What am I doing wrong? Is there a better way to read in the binary of an executable file and immediately write it out to another name? Any code examples?
I need to do it without a system copy in order to simulate writing to disk.
One way is to use the stream inserter for a streambuf:
int WriteFileContentsToNewFile(string inFilename, string outFilename)
{
ifstream infile(inFilename.c_str(), ios::binary);
ofstream outfile(outFilename.c_str(), ios::binary);
outfile << infile.rdbuf();
}
The stream operator>>() performs formatted input even if you open the stream in binary mode. Formatted input expects to see strings of printable characters separated by spaces, but this is not what binary files like executables consist of. You need to read the file with the stream's read() function, and write it with the output stream's write() function.
Off the top of my head: (no error checking)
EDIT: Changed to fix feof bug.
int WriteFileContentsToNewFile(string inFilename, string outFilename)
{
FILE* in = fopen(inFilename.c_str(),"rb");
FILE* out = fopen(outFilename.c_str(),"wb");
char buf[4096]; //1024 is a habit of mine. 4096 is most likely your blocksize. it could also be 2<<13 instead.
int len;
while( (len = fread(buf,1,1024,in)) > 0 )
{
fwrite(buf,1,len,out);
}
fclose(in);
fclose(out);
}
(unix) the system cp command not only copies the contents of the file, but also copies (some) of the file permissions, which include the execute bit.
Make sure your copy also sets the execute bit on the output file as appropriate.