c++ get one line data in txt file - c++

I want to read data from a txt file, but i am not able to get it. I am new to c++.
Here is my code, but it does not work. I used getline(),
ifstream inFile;
string sPassWord;
inFile.open("QdatPassWordconfig.config");
inFile.seekg(0,ios::end);
int length=inFile.tellg();
if (inFile.is_open())
{
while (!inFile.eof())
{
getline(inFile,sPassWord);
cout<<sPassWord<<endl;
}
cout<<"get data from txt file"<<endl;
// here ,I cannot read data from file
cout<<sPassWord<<endl;
}
if(!inFile.is_open() || length==0)
{
cout<<"file is create or write"<<endl;
sPassWord="BdsWUjT26";
ofstream outFile;
outFile.open("QdatPassWordconfig.config");
outFile<<sPassWord<<endl;
outFile.close();
}
inFile.close();
cout<<sPassWord<<endl;

It isn't clear if you are trying to read the first line of the file, the last line of the file, or all the lines of the file. Here program snippets for each possibility:
To read the first line of the file:
// UNTESTED
{
ifstream inFile("QdatPassWordconfig.config");
string sPassWord;
if(std::getline(inFile, sPassWord)) {
std::cout << "Password is: " << sPassWord << "\n";
} else {
std::cout << "No password available.\n"
}
}
To read all of the lines of the file:
// TESTED
#include <iostream>
#include <fstream>
#include <string>
int main ()
{
std::ifstream inFile("QdatPassWordconfig.config");
std::string sPassWord;
while(std::getline(inFile, sPassWord)) {
std::cout << "Password is: " << sPassWord << "\n";
}
}
To read the last line of the file:
// UNTESTED
{
ifstream inFile("QdatPassWordconfig.config");
string sPassWord;
int lineCount = 0;
while(std::getline(inFile, sPassWord)) {
lineCount++;
}
if(lineCount) {
std::cout << "Password is: " << sPassWord << "\n";
} else {
std::cout << "No password available.\n";
}
}

inFile.seekg(0,ios::end);
int length=inFile.tellg();
1.You forgot seek back to the beginning. Like this:
inFile.seekg(0,ios::end);
int length=inFile.tellg();
inFile.seekg(0,ios::beg);
2.You need to practice on your if and else statement.
3.Don't use std::ifstream::eof. Use std::getline.

Do something like this:
// Declare local variables
std::ifstream inFile;
std::string sPassword = "";
::UINT length = 0;
// Attempt to open file
inFile.open( "QdatPassWordconfig.config" );
// Use your if and else statement like this:
// Is inFile open?
if( inFile.is_open( ) )
{
// Read file line by line using std::getline
while( std::getline( inFile, sPassword ) ) {
// Print sPassword
std::cout << sPassword << std::endl;
}
// Done with inFile, close it
inFile.close( );
}
else
{
// Do whatever if inFile can't be open
}

There are so many errors with your code, so I decided to show you how I would have done it (please do read the comments):
void Example( void )
{
// DECLARATION
bool bInputMode = true;
std::fstream ioFile;
::UINT nFileSize = 0;
std::string strPassword = "";
// INITIALIZATION
// *Open or create ioFile
// ioFile can now do both input and output operations
ioFile.open( "Passwords.pw",
std::fstream::in |std::fstream::out | std::fstream::app );
// *Calculate/set the value of bInputMode
// first, calculate the size of the file
// if the size of the file is = 0,
// bInputMode = false - which means to be in output mode
ioFile.seekg( 0, std::ios::end );
if( ( nFileSize = ioFile.tellg( ) ) = 0 )
bInputMode = false;
ioFile.seekg( 0, std::ios::beg );
// DO WHATEVER
// *Since bInputMode == true,
// we shall read each line from ioFile by using std::getline
if( bInputMode )
{
// *Get each line within ioFile and "copy" it to strPassword
// and then print strPassword
// *With std::getline, we could get the spaces
while( std::getline( ioFile, strPassword ) )
std::cout << strPassword << std::endl;
}
// *Since bInputMode == false,
// we shall create a new from ioFile and then write to it
else
{
std::cout << "Creating/writing a new file..." << std::endl;
strPassword = "Password123";
ioFile << strPassword << std::endl;
}
// CLEAN-UP
// We are done with ioFile, close it.
ioFile.close( );
};
Please point out any errors! Some feedback and suggestions would be great as well.

Related

Why am I getting an std::bad_alloc error

I'm having an issue when running the code below. Every time I set the while loop to reach the .eof() it returns a std::bad_alloc
inFile.open(fileName, std::ios::in | std::ios::binary);
if (inFile.is_open())
{
while (!inFile.eof())
{
read(inFile, readIn);
vecMenu.push_back(readIn);
menu.push_back(readIn);
//count++;
}
std::cout << "File was loaded succesfully..." << std::endl;
inFile.close();
}
It runs fine if I set a predetermined number of iterations, but fails when I use the EOF funtion. Here's the code for the read function:
void read(std::fstream& file, std::string& str)
{
if (file.is_open())
{
unsigned len;
char *buf = nullptr;
file.read(reinterpret_cast<char *>(&len), sizeof(unsigned));
buf = new char[len + 1];
file.read(buf, len);
buf[len] = '\0';
str = buf;
std::cout << "Test: " << str << std::endl;
delete[] buf;
}
else
{
std::cout << "File was not accessible" << std::endl;
}
}
Any help you can provide is greatly appreciated.
NOTE: I failed to mention that vecMenu is of type std::vector
and menu is of type std::list
The main problems I see are:
You are using while (!inFile.eof()) to end the loop. See Why is iostream::eof inside a loop condition considered wrong?.
You are not checking whether calls to ifstream::read succeeded before using the variables that were read into.
I suggest:
Changing your version of read to return a reference to ifstream. It should return the ifstream it takes as input. That makes it possible to use the call to read in the conditional of a loop.
Checking whether calls to ifstream::read succeed before using them.
Putting the call to read in the conditional of the while statement.
std::ifstream& read(std::fstream& file, std::string& str)
{
if (file.is_open())
{
unsigned len;
char *buf = nullptr;
if !(file.read(reinterpret_cast<char *>(&len), sizeof(unsigned)))
{
return file;
}
buf = new char[len + 1];
if ( !file.read(buf, len) )
{
delete [] buf;
return file;
}
buf[len] = '\0';
str = buf;
std::cout << "Test: " << str << std::endl;
delete[] buf;
}
else
{
std::cout << "File was not accessible" << std::endl;
}
return file;
}
and
inFile.open(fileName, std::ios::in | std::ios::binary);
if (inFile.is_open())
{
std::cout << "File was loaded succesfully..." << std::endl;
while (read(inFile, readIn))
{
vecMenu.push_back(readIn);
menu.push_back(readIn);
//count++;
}
inFile.close();
}

How to append to one file, then copy said file into another file

I feel like I've tried everything, I can get the first file to append to the second but cannot get the second file into a third. What am I doing wrong?
To be clear I need to take one file, append it to a second file, then put the contents of that second file into a third. I was able to simulate this outcome by putting both files into strings and then putting those strings into a third file, but that's not 'correct' in this problem.
I'm not particular to any way or any technique, I've tried a few and nothing works. This is the latest attempt, still doesn't work for the last step.
Here's my code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string a,b,c;
cout << "Enter 3 file names: ";
cin >> a >> b >> c;
fstream inf;
ifstream two;
fstream outf;
string content = "";
string line = "";
int i;
string ch;
inf.open(a, ios::in | ios:: out | ios::app);
two.open(b);
outf.open(c, ios::in);
//check for errors
if (!inf)
{
cerr << "Error opening file" << endl;
exit(1);
}
if (!two)
{
cerr << "Error opening file" << endl;
exit(1);
}
if (!outf)
{
cerr << "Error opening file" << endl;
exit(1);
}
for(i=0; two.eof() != true; i++)
content += two.get();
i--;
content.erase(content.end()-1);
two.close();
inf << content;
inf.clear();
inf.swap(outf);
outf.close();
inf.close();
return 0;
Here's an idea:
#include <fstream>
using namespace std;
void appendf( const char* d, const char* s )
{
ofstream os( d, ios::app );
if ( ! os )
throw "could not open destination";
ifstream is( s );
if ( ! is )
throw "could not open source";
os << is.rdbuf();
}
int main()
{
try
{
appendf( "out.txt", "1.txt" );
return 0;
}
catch ( const char* x )
{
cout << x;
return -1;
}
}

Need help diagnosing errors in C++ program designed to extract timestamps from an XML file

With some help I've almost completed a program which enables me to extract the timestamps(eg:timestamp="2014-07-08T18:14:16.468Z" ) and only the timestamps from and XML file and output them to a designated output file. However, there are a handful of errors left in my code which have me at wits end, which can't seem to redress. Would someone more experienced with C++ mind helping me out?
The errors appear in lines 35,38, & 47.
Screenshot of errors: http://i.imgur.com/jVUig4T.jpg
Link to XML file: http://pastebin.com/DLVF0cXY
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
using namespace std;
string tempStr;
// escaped double qoute.
string findStr = "timestamp=\"";
ifstream inFile;
ofstream outFile;
outFile.open("Outputdata.txt");
inFile.open("Groupproject.xml");
if (inFile.fail()) {
cout << "Error Opening File" << endl;
system("pause");
exit(1);
}
size_t found;
while (inFile) {
getline(inFile, tempStr);
found = tempStr.find(findStr);
if (found != std::string::npos)
{
break;
}
}
// Erases from beggining to end of timestamp="
tempStr.erase(tempStr.begin(), (found + tempStr.length()));
// Finds index of next double qoute.
found = tempStr.findStr("\"");
if (found = std::string::npos)
{
cerr << "Could not find matching qoute:";
exit(1);
}
// Erases from matching qoute to the end of the string.
tempStr.erase(found, tempStr.end());
cout << "timestamp found" << tempStr << "Saving to outFile" << endl;
outFile << tempStr;
inFile.close();
outFile.close();
system("pause");
return 0;
}
Are you sure you carefully read the reference for all the functions you are using ? Your new friend
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
string tempStr;
string findStr = "timestamp=\""; // escaped double quote
ifstream inFile;
ofstream outFile;
outFile.open( "Outputdata.txt" );
inFile.open( "Groupproject.xml" );
if ( inFile.fail() )
{
cout << "Error Opening File" << endl;
cin.get();
exit( 1 );
}
size_t found;
while ( inFile )
{
getline( inFile, tempStr );
cout << tempStr << endl;
found = tempStr.find( findStr );
if ( found != string::npos )
break;
}
tempStr.erase( 0, found + findStr.length() ); // erases from beggining to end of timestamp="
found = tempStr.find( "\"" ); // finds index of next double quote
if ( found == string::npos )
{
cerr << "Could not find matching quote" << endl;
exit( 1 );
}
tempStr.erase( found, string::npos ); // erases from matching quote to the end of the string.
cout << "timestamp found:" << tempStr << " Saving to outFile" << endl;
outFile << tempStr;
inFile.close();
outFile.close();
cin.get();
return 0;
}

Creating a class with an open file stream

I've created a class which is supposed to read in DNA sequences: It contains an if stream private member:
Interface:
class Sequence_stream {
const char* FileName;
std::ifstream FileStream;
std::string FileFormat;
public:
Sequence_stream(const char* Filename, std::string Format);
NucleotideSequence get();
};
Implementation:
Sequence_stream::Sequence_stream(const char* Filename, std::string Format)
{
FileName = Filename;
FileStream.open(FileName);
FileFormat = Format;
std::cout << "Filestream is open: " << FileStream.is_open() << std::endl;
}
NucleotideSequence Sequence_stream::get()
{
if (FileStream.is_open())
{
char currentchar;
int basepos = 0;
std::string name;
std::vector<Nucleotide> sequence;
currentchar = FileStream.get();
if (currentchar == '>' && false == FileStream.eof()) { // Check that the start of the first line is the fasta head character.
currentchar = FileStream.get(); // Proceed to get the full name of the sequence. Get characters until the newline character.
while(currentchar != '\n' && false == FileStream.eof())
{
if (true == FileStream.eof()) {
std::cout << "The file ends before we have even finished reading in the name. Returning an empty NucleotideSequence" << std::endl;
return NucleotideSequence();
}
name.append(1, currentchar);
currentchar = FileStream.get();
} // done getting names, now let's get the sequence.
currentchar = FileStream.get();
while(currentchar != '>' && false == FileStream.eof())
{
if(currentchar != '\n'){
basepos++;
sequence.push_back(Nucleotide(currentchar, basepos));
}
currentchar = FileStream.get();
}
if(currentchar == '>')
{
FileStream.unget();
}
return NucleotideSequence(name, sequence);
} else {
std::cout << "The first line of the file was not a fasta format description line beginning with '>'. Are you sure the file is of FASTA format?" << std::endl;
return NucleotideSequence();
}
} else {
std::cout << "The filestream is not open..." << std::endl;
return NucleotideSequence();
}
}
However if I test it:
int main()
{
std::cout << "Let's try and read in a sequence!" << std::endl;
std::cout << "First we'll create a stream!" << std::endl;
Sequence_stream MyDNAStream("~/Dropbox/1_20dd5.fasta", "fasta");
std::cout << "Done!" << std::endl;
std::cout << "Now let's try and get a sequence!" << endl;
NucleotideSequence firstsequence = MyDNAStream.get();
return 0;
}
I see that the if stream is not open:
Let's try and read in a sequence!
First we'll create a stream!
Filestream is open: 0
Done!
The filestream is not open...
logout
[Process completed]
Although I thought the constructor function opens the if stream. What do I need to do to correct this so as the object is created and contains an open stream? (I know I'm yet to include a destructor which will close the stream upon destruction of the object).
Thanks,
Ben.
Your example shows that is_open returned false. I think you should check in your constructor that the file is indeed open, and throw if not.
In your case, I suspect this is due to passing "~/Dropbox/1_20dd5.fasta" as an input parameter. Did you test with a full pathname, with no ~? I have no knowledge of a C++ library that handles real path expansion (like python's os.path).

saving the changes in file

Ojective: To open config file, look for a particular line which has tag and change its value
Example:
config .txt
bla bla
bla bla
SYSTEM_A_EXTERNAL_IP=192.168.0.57 // need to change ip address
bla bla
bla bla
What I have done so far: My code open the file and look for the particular line which has tag and change its value .
Problem: I failed to see those changes in the actual file. I am aware that ofstream will write into line but if I do ofstream instead of ifstream getline function gets an error.
Code1:
bool SetIpAddr(string & iAddr)
{
bool check= false;
// Open file
ifstream iFile(IpConfigFile.c_str(), ios_base::out|ios::app | ios::binary);
if(iFile.is_open())
{
check= true;
}
// Read content of ipconf file searching for the value of Head Id Name
if(true == check)
{
string TargetName = SystemAIdValue + ExternalIpNamePostfix+ ValueAssignmentCharacter;
string outbuf;
while( !iFile.eof() )
{
getline(iFile, outbuf);
// find the matching string
if( 0 == outbuf.compare(0,TargetName.size(),TargetName) )
{
outbuf.erase(outbuf.begin()+TargetName.size(), outbuf.end());
outbuf.insert(0+TargetName.size(), iAddr);
std::cout<< " after insertion " << outbuf << std::endl;
break;
}
}
}
// Close (input) file
if( iFile.is_open() )
{
iFile.close();
}
return check;
}
Code2: Also doesnt work.
bool SetIpAddr(string & aIpAddr)
{
bool lResult = false;
std::fstream ifile("platform_ip_config");
string lTargetIp = HeadAIdValue + ExternalIpNamePostfix+ ValueAssignmentCharacter;
std::deque<std::string>lines;
std::string inbuf;
while( std::getline(ifile, inbuf));
{
std::cout<<" we are in while"<<std::endl;
std::cout<<" getline =="<< inbuf<< std::endl;
std::cout<<" ip =="<<lTargetIp<< std::endl;
if( 0 == inbuf.compare(0,lTargetIp.size(),lTargetIp) )
{
std::cout<<" we are in matching"<<std::endl;
std::cout<< inbuf << std::endl;
inbuf.erase(inbuf.begin()+lTargetIp.size(), inbuf.end());
std::cout<<" after erase " << inbuf << std::endl;
inbuf.insert(0+lTargetIp.size(), aIpAddr);
std::cout<< " after insertinon " << inbuf << std::endl;
}
lines.push_back(inbuf);
}
ifile.seekg (0, ios::beg );
std::copy(lines.begin(), lines.end(),
std::ostream_iterator<std::string>(ifile, "\n"));
}
lines.push_back(inbuf);
}
ifile.seekg (0, ios::beg );
std::copy(lines.begin(), lines.end(),
std::ostream_iterator<std::string>(ifile, "\n"));
}
What you are doing is inherently tricky, writing to the middle of a file hoping the result will remain in place.
for example
192.168.120.111
uses up a lot more characters than
10.10.10.10
the way i would do this is read the whole files into lines.
std::fstream file(file_name);
std::deque<std::string> lines;
std::string temp;
while(std::getline(file, temp))
{
//detect that this the line you want
if(this_is_my_line(temp))
{
//do what you need to do to the string
modify(temp);
}
lines.push_back(temp);
}
file.seekg (0, ios::beg
//write back to file
std::copy(lines.begin(), lines.end(),
std::ostream_iterator<std::string>(file, "\n"));
Please note you do not need to explicitly close a file in C++, the RAII semantics will close it for you, by doing it your self your increasing the opportunity for bugs to creep into your code.
THIS WORKS ON MY SYSTEM
#include <iostream>
#include <fstream>
#include <string>
#include <deque>
#include <iterator>
int main()
{
std::string line;
const std::string token("SYSTEM_A_EXTERNAL_IP=");
std::deque<std::string> lines;
{
std::ifstream file("config.txt");
while(std::getline(file, line))
{
if(std::equal(token.begin(), token.end(), line.begin()))
{
line=token+"10.10.10.5"; //or whatever
}
lines.push_back(line);
}
}
{
std::ofstream file("config.txt");
std::copy(lines.begin(), lines.end(),
std::ostream_iterator<std::string>(file,"\n"));
}
return 0;
}
By using an ifstream you are opening the file for reading, if you use the fstream base class instead you should be able modify the file
Another approach is to read the entire file into a buffer, make changes to the buffer and overwrite the original file using the ofstream class