读取结构化值时触发错误
Error triggered when reading structured values
我想弄清楚为什么“使用 C++ 编程原理和实践”中的这段代码会触发错误(“错误阅读”):
#include "D:\std_lib_facilities.h"
/*
get it from: https://github.com/ltr01/Programming-
_Principles_and_Practice_Using_Cpp/blob/master/std_lib_facilities.h
*/
struct Reading
{
int day;
int hour;
double temperature;
};
istream &operator>>(istream &is, Reading &r)
// format: ( 3 4 9.7 )
{
char ch1;
if (is >> ch1 && ch1 != '(') // first try the format (day, hour, temperature)
{ // could it be a Reading?
is.unget(); // puts the character back so we can read it in some other way
is.clear(ios_base::failbit); // puts the istream in fail() state
return is; // return allows us to try to read in some other way
}
char ch2;
int d;
int h;
double t;
is >> d >> h >> t >> ch2;
if (!is || ch2 != ')') // the istream it's not good
error("bad reading"); // messed-up reading = we bail out because the format is wrong
return is;
r.day = d;
r.hour = h;
r.temperature = t;
return is; //
}
void fill_from_file(vector<Reading> &v, const string &name)
{
ifstream ist{name}; // open file for reading
if (!ist)
error("can't open input file ", name); //
// . . . use ist . . .
for (Reading r; ist >> r;)
v.push_back(r);
}
int main()
try
{
vector<Reading> day1; // a day is a vector of readings
fill_from_file(day1, "10.5_reading_in.txt");
for (Reading r : day1)
cout << r.day << ' ' << r.hour << ' ' << r.temperature << '\n';
}
catch (exception &e)
{
cerr << "Error: " << e.what() << endl;
return 1;
}
catch (...)
{
cerr << "Unknown exception!\n";
return 2;
}
当我尝试读取此文件时:
(1 1 1.1)
(2 2 2.2)
(3 3 3.3)
(4 4 4.4)
(5 5 5.5)
(6 6 6.6)
(7 7 7.7)
(8 8 8.8)
(9 9 9.9)
我对发生的事情的理解是这样的:
我们读取第一个字符,如果它不是“(”,它会将字符放回 istream(使用 unget),将状态设置为失败,returns istream尝试以其他方式阅读它
现在它试图在没有括号的情况下读取它(这是书中的代码)但是因为第一个字符确实是“(”我得到了“错误阅读”错误
我试图通过读取 ch1 来更改代码,如下所示,但错误(“错误读取”)再次触发:
是 >> ch1 >> d >> h >> t >> ch2;
我做错了什么?非常感谢您的回答!
更新:感谢 Manuel 的回复,但我无法使其与您的修改一起工作。相反,如果我在到达“文件末尾”时退出该功能,它似乎会起作用。如果我不把 "return is" 放在那里,那么条件 (ch2 != ')') 总是为真,我得到错误 "bad reading" :
// test for end of file or istream error
if (!is) // meaning when is=0 - when it reaches the end
{
if (is.eof())
cout << "Finished" << '\n';
return is;
if (is.fail())
error("wrong character type");
}
// test for wrong file format
if (ch2 != ')')
{
cout << "Readed: " << ch2 << '\n';
error("bad reading");
}
如果你设置两个条件来检查输入流和字符读取,你将看到错误:
if (!is) {
cout << "Finished" << endl;
return is;
}
if (ch2 != ')') { // the istream it's not good
cout << "Readed: " << ch2 << endl;
error("bad reading"); // messed-up reading = we bail out because the format is wrong
}
输出:
Finished
Readed:
bad reading
您的文件已完成。全部读取正确,但文件结束。
你还有一个额外的 return:
if (!is || ch2 != ')')
error("bad reading");
return is; // <-- I suppose this was for debugging, remove it
r.day = d;
r.hour = h;
r.temperature = t;
return is; //
经过这些更改,我的输出是:
Finished
Readed:
bad reading
1 1 1.1
2 2 2.2
3 3 3.3
4 4 4.4
5 5 5.5
6 6 6.6
7 7 7.7
8 8 8.8
9 9 9.9
在您上次编辑的代码中:
if (is.eof())
cout << "Finished" << '\n';
return is;
应该有花括号:
if (is.eof()) {
cout << "Finished" << '\n';
return is;
}
C++ 中的缩进没有任何意义。
我想弄清楚为什么“使用 C++ 编程原理和实践”中的这段代码会触发错误(“错误阅读”):
#include "D:\std_lib_facilities.h"
/*
get it from: https://github.com/ltr01/Programming-
_Principles_and_Practice_Using_Cpp/blob/master/std_lib_facilities.h
*/
struct Reading
{
int day;
int hour;
double temperature;
};
istream &operator>>(istream &is, Reading &r)
// format: ( 3 4 9.7 )
{
char ch1;
if (is >> ch1 && ch1 != '(') // first try the format (day, hour, temperature)
{ // could it be a Reading?
is.unget(); // puts the character back so we can read it in some other way
is.clear(ios_base::failbit); // puts the istream in fail() state
return is; // return allows us to try to read in some other way
}
char ch2;
int d;
int h;
double t;
is >> d >> h >> t >> ch2;
if (!is || ch2 != ')') // the istream it's not good
error("bad reading"); // messed-up reading = we bail out because the format is wrong
return is;
r.day = d;
r.hour = h;
r.temperature = t;
return is; //
}
void fill_from_file(vector<Reading> &v, const string &name)
{
ifstream ist{name}; // open file for reading
if (!ist)
error("can't open input file ", name); //
// . . . use ist . . .
for (Reading r; ist >> r;)
v.push_back(r);
}
int main()
try
{
vector<Reading> day1; // a day is a vector of readings
fill_from_file(day1, "10.5_reading_in.txt");
for (Reading r : day1)
cout << r.day << ' ' << r.hour << ' ' << r.temperature << '\n';
}
catch (exception &e)
{
cerr << "Error: " << e.what() << endl;
return 1;
}
catch (...)
{
cerr << "Unknown exception!\n";
return 2;
}
当我尝试读取此文件时:
(1 1 1.1)
(2 2 2.2)
(3 3 3.3)
(4 4 4.4)
(5 5 5.5)
(6 6 6.6)
(7 7 7.7)
(8 8 8.8)
(9 9 9.9)
我对发生的事情的理解是这样的:
我们读取第一个字符,如果它不是“(”,它会将字符放回 istream(使用 unget),将状态设置为失败,returns istream尝试以其他方式阅读它
现在它试图在没有括号的情况下读取它(这是书中的代码)但是因为第一个字符确实是“(”我得到了“错误阅读”错误
我试图通过读取 ch1 来更改代码,如下所示,但错误(“错误读取”)再次触发:
是 >> ch1 >> d >> h >> t >> ch2;
我做错了什么?非常感谢您的回答!
更新:感谢 Manuel 的回复,但我无法使其与您的修改一起工作。相反,如果我在到达“文件末尾”时退出该功能,它似乎会起作用。如果我不把 "return is" 放在那里,那么条件 (ch2 != ')') 总是为真,我得到错误 "bad reading" :
// test for end of file or istream error
if (!is) // meaning when is=0 - when it reaches the end
{
if (is.eof())
cout << "Finished" << '\n';
return is;
if (is.fail())
error("wrong character type");
}
// test for wrong file format
if (ch2 != ')')
{
cout << "Readed: " << ch2 << '\n';
error("bad reading");
}
如果你设置两个条件来检查输入流和字符读取,你将看到错误:
if (!is) {
cout << "Finished" << endl;
return is;
}
if (ch2 != ')') { // the istream it's not good
cout << "Readed: " << ch2 << endl;
error("bad reading"); // messed-up reading = we bail out because the format is wrong
}
输出:
Finished
Readed:
bad reading
您的文件已完成。全部读取正确,但文件结束。
你还有一个额外的 return:
if (!is || ch2 != ')')
error("bad reading");
return is; // <-- I suppose this was for debugging, remove it
r.day = d;
r.hour = h;
r.temperature = t;
return is; //
经过这些更改,我的输出是:
Finished
Readed:
bad reading
1 1 1.1
2 2 2.2
3 3 3.3
4 4 4.4
5 5 5.5
6 6 6.6
7 7 7.7
8 8 8.8
9 9 9.9
在您上次编辑的代码中:
if (is.eof())
cout << "Finished" << '\n';
return is;
应该有花括号:
if (is.eof()) {
cout << "Finished" << '\n';
return is;
}
C++ 中的缩进没有任何意义。