与 fileIO 中的空格混淆
Confusion with spaces in fileIO
我有很好的输入文件,如下所示:
734 220 915 927 384 349 79 378 593 46 2 581 500 518 556 771 697
571 891 181 537 455
和看起来像这样的错误输入文件:
819 135 915 927 384 349 79 378 593 46 2 581 500 518 556 771 697
551 425 815 978 626 207 931 ABCDEFG 358 16 875 936 899 885 195 565
571 891 181 537 110
两个文件末尾的最后一个整数后面都有一个 space。我正在尝试用 C++ 编写一个脚本,它将读取所有整数,除非像第二个示例中那样存在 char/string,在这种情况下它会提醒我这一点。我试过这样写:
int main()
{
int n;
bool badfile = false;
ifstream filein("data.txt");
while (!filein.eof())
{
filein >> n;
if(filein.fail())
{
cout << "Not an integer." << endl;
badfile = true;
break;
}
cout << n << " ";
}
cout << endl << "file check: " << badfile << endl;
}
但 filein.fail()
是由好文件末尾的 space 以及坏文件中的 char/string 触发的。那么我该如何设置它以使其忽略白色 spaces 呢?为什么它只有在末尾有 space 时才会失败,而不是完全失败 space 或完全忽略它们?
主要问题是如何在流上测试 eof()
...它仅在 后设置 输入尝试尝试读取更多字符文件结尾。首先使用 std::ws
来消耗空白意味着 eof
检测可以是可靠的:如果你不是那么在 eof()
你知道你在一些非空白输入应该是一个数字- 如果不是你输入的内容有误。
建议代码:
#include <iostream>
#include <fstream>
#include <iomanip>
int main()
{
if (ifstream filein("data.txt"))
{
while (filein >> std::ws && !filein.eof())
{
int n;
if (filein >> n)
cout << n << ' ';
else
{
std::cerr << "error in input\n";
exit(EXIT_FAILURE);
}
}
std::cout << '\n';
}
else
std::cerr << "unable to open data.txt\n";
}
下面显示了一个替代方法,它可能更容易理解,但并不完全可靠。问题是尽管有错误的输入,例如尾随 -
或 +
,您仍然可以到达 EOF,因为在尝试读取数字时会消耗它,但它本身不足以构成成功的解析的一个数字。只有已知文件有一个 '\n'
终止最后一行,这才是可靠的:
int n;
while (filein >> n)
cout << n << " ";
filein.clear(); // remove the error state
if (filein.peek() != istream::traits_type::eof())
{
// while didn't reach EOF; must be parsing error
std::error << "invalid input\n";
exit(EXIT_FAILURE);
}
我建议
ifstream filein("data.txt");
while (filein >> n)
cout << n << " ";
if (filein.fail()) {
cout << "Not an integer." << endl;
badfile = true;
}
cout << endl << boolalpha << badfile << endl;
我有很好的输入文件,如下所示:
734 220 915 927 384 349 79 378 593 46 2 581 500 518 556 771 697
571 891 181 537 455
和看起来像这样的错误输入文件:
819 135 915 927 384 349 79 378 593 46 2 581 500 518 556 771 697
551 425 815 978 626 207 931 ABCDEFG 358 16 875 936 899 885 195 565
571 891 181 537 110
两个文件末尾的最后一个整数后面都有一个 space。我正在尝试用 C++ 编写一个脚本,它将读取所有整数,除非像第二个示例中那样存在 char/string,在这种情况下它会提醒我这一点。我试过这样写:
int main()
{
int n;
bool badfile = false;
ifstream filein("data.txt");
while (!filein.eof())
{
filein >> n;
if(filein.fail())
{
cout << "Not an integer." << endl;
badfile = true;
break;
}
cout << n << " ";
}
cout << endl << "file check: " << badfile << endl;
}
但 filein.fail()
是由好文件末尾的 space 以及坏文件中的 char/string 触发的。那么我该如何设置它以使其忽略白色 spaces 呢?为什么它只有在末尾有 space 时才会失败,而不是完全失败 space 或完全忽略它们?
主要问题是如何在流上测试 eof()
...它仅在 后设置 输入尝试尝试读取更多字符文件结尾。首先使用 std::ws
来消耗空白意味着 eof
检测可以是可靠的:如果你不是那么在 eof()
你知道你在一些非空白输入应该是一个数字- 如果不是你输入的内容有误。
建议代码:
#include <iostream>
#include <fstream>
#include <iomanip>
int main()
{
if (ifstream filein("data.txt"))
{
while (filein >> std::ws && !filein.eof())
{
int n;
if (filein >> n)
cout << n << ' ';
else
{
std::cerr << "error in input\n";
exit(EXIT_FAILURE);
}
}
std::cout << '\n';
}
else
std::cerr << "unable to open data.txt\n";
}
下面显示了一个替代方法,它可能更容易理解,但并不完全可靠。问题是尽管有错误的输入,例如尾随 -
或 +
,您仍然可以到达 EOF,因为在尝试读取数字时会消耗它,但它本身不足以构成成功的解析的一个数字。只有已知文件有一个 '\n'
终止最后一行,这才是可靠的:
int n;
while (filein >> n)
cout << n << " ";
filein.clear(); // remove the error state
if (filein.peek() != istream::traits_type::eof())
{
// while didn't reach EOF; must be parsing error
std::error << "invalid input\n";
exit(EXIT_FAILURE);
}
我建议
ifstream filein("data.txt");
while (filein >> n)
cout << n << " ";
if (filein.fail()) {
cout << "Not an integer." << endl;
badfile = true;
}
cout << endl << boolalpha << badfile << endl;