我有以下代码来读取文本文件.
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
有问题的文本文件的内容是
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
Run Code Online (Sandbox Code Playgroud)
我得到的输出是
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
Run Code Online (Sandbox Code Playgroud)
我想要的输出是:
PackageId:994
994
Name:basket
basket
Version:1.80-1
1.80-1
...
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
while .good或者while !.eof是几乎总是错的.抛弃任何书告诉你这样做,而是这样做.
在这种情况下,更改的代码看起来有点像这样:
const string FILENAME = PACKAGES_DIR + pname;
//the arguments to ifstream is a cstring and hence the conversion must be made
ifstream freader(FILENAME.c_str(), ios::in);
if (freader) {
string line;
while (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;
}
}
Run Code Online (Sandbox Code Playgroud)
你没有std::string::find正确使用.
line.find("PackageId:")返回"搜索内容的字符串中第一次出现的位置",npos如果未找到匹配则返回成员值.
这与未对第一个参数执行边界检查相结合std::string::substr会导致字符串出现问题.
相反,写:
if (line.find("PackageId:") != std::string::npos)
Run Code Online (Sandbox Code Playgroud)
cout<<line.find(8)<<endl;应该说substr,不是find.
您的代码具有上述一些修复:
const string FILENAME = PACKAGES_DIR + pname;
//the arguments to ifstream is a cstring and hence the conversion must be made
ifstream freader(FILENAME.c_str(), ios::in);
if (freader) {
string line;
while (getline(freader,line)) { // <-----
cout << line << endl;
if (line.find("PackageId:") != std::string::npos && line.size() > 11)
cout << line.substr(11) << endl;
else if (line.find("Name:") != std::string::npos && line.size() > 5)
cout << line.substr(5) << endl;
else if (line.find("Version:") != std::string::npos && line.size() > 8)
cout << line.substr(8) << endl;
else
cout << line << endl;
}
}
Run Code Online (Sandbox Code Playgroud)