I have the following code to read a text file.
const string FILENAME = PACKAGES_DIR + pname;
//the arguments to ifstream is a cstring and hence the conversion must be made
ifstream freader;
freader.open(FILENAME.c_str(),ios::in);
if(freader.is_open())
{
while(freader.good())
{
string line;
getline(freader,line);
cout<<line<<endl;
if(line.find("PackageId:"))
{
cout<<line.substr(11)<<endl;
}
else if(line.find("Name:"))
{
cout<<line.substr(5)<<endl;
}
else if(line.find("Version:"))
{
cout<<line.find(8)<<endl;
}
else
{
cout<<line<<endl;
}
}
}
The contents of the text file in question is
PackageId:994
Name:basket
Version:1.80-1
Deps:kdebase-runtime,libc0.1,libc0.1-udeb,libc6,libc6-udeb,libc6.1,libc6.1-udeb,libgcc1,libgpg-error0,libgpgme11,libkdecore5,libkdeui5,libkfile4,libkio5,libkparts4,libkutils4,libphonon4,libqimageblitz4,libqt4-dbus,libqt4-network,libqt4-qt3support,libqt4-svg,libqt4-xml,libqtcore4,libqtgui4,libstdc++6,libunwind7,libx11-6,phonon
The output that I get is
PackageId:994
geId:994
Name:basket
Version:1.80-1
0-1
Deps:kdebase-runtime,libc0.1,libc0.1-udeb,libc6,libc6-udeb,libc6.1,libc6.1-udeb,libgcc1,libgpg-error0,libgpgme11,libkdecore5,libkdeui5,libkfile4,libkio5,libkparts4,libkutils4,libphonon4,libqimageblitz4,libqt4-dbus,libqt4-network,libqt4-qt3support,libqt4-svg,libqt4-xml,libqtcore4,libqtgui4,libstdc++6,libunwind7,libx11-6,phonon
e-runtime,libc0.1,libc0.1-udeb,libc6,libc6-udeb,libc6.1,libc6.1-udeb,libgcc1,libgpg-error0,libgpgme11,libkdecore5,libkdeui5,libkfile4,libkio5,libkparts4,libkutils4,libphonon4,libqimageblitz4,libqt4-dbus,libqt4-network,libqt4-qt3support,libqt4-svg,libqt4-xml,libqtcore4,libqtgui4,libstdc++6,libunwind7,libx11-6,phonon
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr
The output that I wanted is:
PackageId:994
994
Name:basket
basket
Version:1.80-1
1.80-1
...
What have I done wrong?
Problem 1
while .goodorwhile !.eofis almost always wrong. Throw away whatever book told you to do that, and do this instead.In this case, the changed code looks a bit like this:
Problem 2
You’re not using
std::string::findcorrectly.line.find("PackageId:")returns either “the position of the first occurrence in the string of the searched content”, or the member valuenposif the match is not found.This combined with not performing bounds checks on the first parameter to
std::string::substris causing issues with your strings.Instead, write:
Problem 3
cout<<line.find(8)<<endl;should saysubstr, notfind.Your code with some of the above fixed: