在使用GCC 5.2.1编译的程序中,当ifstream
到达文件末尾时,basic_ios::eof()
的状态不会切换到if(eof())
,即条件{{1}在文件结束后评估到false
- 而在Visual Studio 2015上编译的相同代码表现如预期:当到达文件末尾时,basic_ios::eof()
评估为{{1} } true
条件。
我将if
替换为if(eof())
,然后替换为if(bad())
,并将所有评估为if(fail())
。但是,当我放置false
宏时,EOF
会计算为if(EOF)
- 就像true
对VS编译的程序所做的那样。
if(eof())
不能使用GCC编译的程序可能是什么原因?
PS:以下是该程序的代码
std::basic_ios::eof()
#include <string>
#include <iostream>
#include <fstream>
#include <regex>
using namespace std;
using namespace std::chrono;
int ex10()
{
ifstream in{ "school.txt" };
if (!in) cout << "The 'school.txt' file was not opened.\n";
string line;
regex header{ R"(^([\w]+)(\t{2}\w+\s*\w*)(\t\w+\s*\w*)(\t\w+\s*\w*)$)" };
regex row{ R"(^(\w+\s*\w*)(\t{1,2}\d+)(\t{2}\d+)(\t{2}\d+)$)" };
if (getline(in, line)) {
smatch matches;
if (!regex_match(line, matches, header))
cerr << "Wrong header format.\n";
}
int linenum = 0;
int boys = 0;
int girls = 0;
ofstream out{ "schoolCompressed.txt" };
if (!out) cout << "The output file was not created.\n";
string prevLine;
int accumBoys;
int accumGirls;
int accumTot;
while (getline(in, line)) {
++linenum;
smatch matches;
if (!regex_match(line, matches, row))
cerr << "Row #" << linenum << " doesn't match the format.\n";
int curr_boy = stoi(matches[2]);
int curr_girl = stoi(matches[3]);
int curr_total = stoi(matches[4]);
if (curr_boy + curr_girl != curr_total)
cerr << "Wrong children number in line #" << linenum << '\n';
if (line[0] != prevLine[0]) {
if (linenum != 1) out << prevLine[0] << "\t\t" << accumBoys << "\t\t"
<< accumGirls << "\t\t" << accumTot << '\n';
accumBoys = curr_boy;
accumGirls = curr_girl;
accumTot = curr_total;
}
else if (line[0] == prevLine[0]) {
accumBoys += curr_boy;
accumGirls += curr_girl;
accumTot += curr_total;
}
if (EOF && curr_boy == boys && curr_girl == girls) { out << line; return 0; } //this works on GCC
//if (in.eof() && curr_boy == boys && curr_girl == girls) { out << line; return 0; } <= this works on VS 2015
boys += curr_boy;
girls += curr_girl;
prevLine = line;
}
cerr << "Somehow the program didn't manage to complete its task :(.\n";
return 1;
}
int main()
{
ex10();
}
文件的文本
school.txt
答案 0 :(得分:3)
EOF是一个常量整数的宏,所以
并不奇怪Syntax error in field definition
&#34;工作&#34;。它只是没有做你期望的,这是检查文件结束。
仅当io操作失败时才应使用 if (EOF && curr_boy == boys && curr_girl == girls)
。
doc规定了
std :: basic_ios :: eof仅报告最多设置的流状态 最近的I / O操作。它不检查关联的数据源。例如,如果最近的I / O是get(),它返回文件的最后一个字节, eof()返回false 。 next get()无法读取任何内容并设置eofbit。只有这样eof()才会返回true
在您的代码中
eof()
预期的行为是GCC的行为。要知道您在文件的末尾,您应该尝试进一步阅读。这与
类似while (getline(in, line)) {
...
if (in.eof())
...
}
你应该将curr_boy和条件移出while循环并消除eof测试
while (!in.eof()) {
...
getline(in, line)
...
}
答案 1 :(得分:0)
您是否使用相同操作系统的相同文件?
如果getline
函数在看到eof
之前到达文件末尾,则会设置'\n'
标记。这只能发生在文件的最后一行。
您应该将结束测试移动到外部 while循环,我们知道当最新的getline
无法读取另一行时,我们已经到达文件的末尾。