ECC vs GCC 5.2.1上的basic_ios :: eof()

时间:2017-02-09 10:56:25

标签: c++ visual-studio gcc ifstream

在使用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

2 个答案:

答案 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无法读取另一行时,我们已经到达文件的末尾。