C++ 为什么建议对文本和数字进行差异 EOF 检查?
C++ Why diff EOF checks recommended for text vs numeric?
我的教科书建议在处理文本数据时使用成员访问器方法 iStreamVar.eof()
,在处理数字数据时使用 while (iStreamVar)
。
有人可以解释为什么这很重要吗?
引自书本:
Using the function eof to determine the end-of-file status works best if the input is text. The earlier method of determining the end-of-file status works best if the input consists of numeric data.
这是主题中唯一提到的内容。在此之后,它只是解释了这个过程是如何工作的。
用什么方法判断数据结束取决于你的使用方式。我的猜测是,你的教科书提到的两种方法都用错了,所以它们在不同的情况下都失败了。这就是为什么它建议在不同的情况下使用不同的方法。
正确的方法并不简单,这取决于错误恢复能力对您的重要性。
如果你想读取一个 space 分隔的流,其中包含数字,并且你确定文件不包含错误,代码最简单:
int value;
while (iStreamVar >> value)
{
...
}
请注意,这不是两个原始选项中的任何一个。
如果您的文件包含 space 分隔的文本数据,并且您确定没有错误,请使用相同的代码(但将临时变量声明为 string
而不是 int
).
如果您想检测错误并从错误中恢复,请使用更精细的代码。但我不能向您推荐任何特定的代码结构——这取决于您在出现错误时究竟想做什么。还有:
- 文本记录是由 space 还是换行符分隔的?
- 如果输入的文本文件包含空行怎么办?
- 数字 - 是否为浮点数?
- 数字 - 如果数字数据中有像
a
这样的杂散字符,怎么办?
所以没有单一的正确方法来进行错误恢复的正确输入。
除非问题中没有显示上下文中的重要内容,否则该引用是无稽之谈。
从文件读取并检查是否成功的方法是从文件读取:
int data;
if (std::cin >> data)
std::cout << "read succeeded, value is " << data << '\n';
std::string data;
if (std::cin >> data)
std::cout << "read succeeded, value is " << data << '\n';
std::string data;
if (std::getline(std::cin, data)
std::cout << "read succeeded, value is " << data << '\n';
如果尝试读取 失败,您可以调用 .eof()
来查明失败是否是因为输入位于文件末尾。与一些初学者的期望(以及某些语言所做的)相反,如果 .eof()
returns false 它确实 not 意味着输入流中仍有数据.在成功读取消耗完剩余输入后,流可能 在 文件末尾。 .eof()
将 return 为假,但下一次尝试读取将失败,之后,.eof()
将 return 为真。
std::stringstream input("1234");
int data;
input >> data; // succeeds
std::cout << input.eof() << '\n'; // outputs 0, no failure
input >> data; // fails, no more input
std::cout << input.eof() << '\n'; // outputs 1, failed because at end of file
我的教科书建议在处理文本数据时使用成员访问器方法 iStreamVar.eof()
,在处理数字数据时使用 while (iStreamVar)
。
有人可以解释为什么这很重要吗?
引自书本:
Using the function eof to determine the end-of-file status works best if the input is text. The earlier method of determining the end-of-file status works best if the input consists of numeric data.
这是主题中唯一提到的内容。在此之后,它只是解释了这个过程是如何工作的。
用什么方法判断数据结束取决于你的使用方式。我的猜测是,你的教科书提到的两种方法都用错了,所以它们在不同的情况下都失败了。这就是为什么它建议在不同的情况下使用不同的方法。
正确的方法并不简单,这取决于错误恢复能力对您的重要性。
如果你想读取一个 space 分隔的流,其中包含数字,并且你确定文件不包含错误,代码最简单:
int value;
while (iStreamVar >> value)
{
...
}
请注意,这不是两个原始选项中的任何一个。
如果您的文件包含 space 分隔的文本数据,并且您确定没有错误,请使用相同的代码(但将临时变量声明为 string
而不是 int
).
如果您想检测错误并从错误中恢复,请使用更精细的代码。但我不能向您推荐任何特定的代码结构——这取决于您在出现错误时究竟想做什么。还有:
- 文本记录是由 space 还是换行符分隔的?
- 如果输入的文本文件包含空行怎么办?
- 数字 - 是否为浮点数?
- 数字 - 如果数字数据中有像
a
这样的杂散字符,怎么办?
所以没有单一的正确方法来进行错误恢复的正确输入。
除非问题中没有显示上下文中的重要内容,否则该引用是无稽之谈。
从文件读取并检查是否成功的方法是从文件读取:
int data;
if (std::cin >> data)
std::cout << "read succeeded, value is " << data << '\n';
std::string data;
if (std::cin >> data)
std::cout << "read succeeded, value is " << data << '\n';
std::string data;
if (std::getline(std::cin, data)
std::cout << "read succeeded, value is " << data << '\n';
如果尝试读取 失败,您可以调用 .eof()
来查明失败是否是因为输入位于文件末尾。与一些初学者的期望(以及某些语言所做的)相反,如果 .eof()
returns false 它确实 not 意味着输入流中仍有数据.在成功读取消耗完剩余输入后,流可能 在 文件末尾。 .eof()
将 return 为假,但下一次尝试读取将失败,之后,.eof()
将 return 为真。
std::stringstream input("1234");
int data;
input >> data; // succeeds
std::cout << input.eof() << '\n'; // outputs 0, no failure
input >> data; // fails, no more input
std::cout << input.eof() << '\n'; // outputs 1, failed because at end of file