提问人:user589321 提问时间:3/4/2022 最后编辑:user589321 更新时间:3/4/2022 访问量:61
使用 Windows 控制台时,getline() 在到达 EOF 时是否总是切换 failbit?
Does getline() always toggle the failbit when it reaches EOF when using Windows console?
问:
根据我阅读的帖子和我自己的测试,要在 Windows 终端中发送 EOF 字符,用户必须在自己的行上键入 + 并按 Enter。例如,示例 1 发送 EOF,但示例 2 不发送:CtrlZ
示例 1:
this is a test
of EOF in Windows
^Z
示例 2:
this is a test
of EOF in Windows^Z
示例 1 将切换 和 何时调用。我一直在试图弄清楚如何在不切换 .为了更好地理解发生了什么,我检查了 MSVC 中的源代码:failbit
eofbit
getline
eofbit
failbit
getline
// FUNCTION TEMPLATE getline
template <class _Elem, class _Traits, class _Alloc>
basic_istream<_Elem, _Traits>& getline(basic_istream<_Elem, _Traits>&& _Istr,
basic_string<_Elem, _Traits, _Alloc>& _Str,
const _Elem _Delim) { // get characters into string, discard delimiter
using _Myis = basic_istream<_Elem, _Traits>;
typename _Myis::iostate _State = _Myis::goodbit;
bool _Changed = false;
const typename _Myis::sentry _Ok(_Istr, true);
if (_Ok) { // state okay, extract characters
_TRY_IO_BEGIN
_Str.erase();
const typename _Traits::int_type _Metadelim = _Traits::to_int_type(_Delim);
typename _Traits::int_type _Meta = _Istr.rdbuf()->sgetc();
for (;; _Meta = _Istr.rdbuf()->snextc()) {
if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit
_State |= _Myis::eofbit;
break;
} else if (_Traits::eq_int_type(_Meta, _Metadelim)) { // got a delimiter, discard it and quit
_Changed = true;
_Istr.rdbuf()->sbumpc();
break;
} else if (_Str.max_size() <= _Str.size()) { // string too large, quit
_State |= _Myis::failbit;
break;
} else { // got a character, add it to string
_Str += _Traits::to_char_type(_Meta);
_Changed = true;
}
}
_CATCH_IO_(_Myis, _Istr)
}
if (!_Changed) {
_State |= _Myis::failbit;
}
_Istr.setstate(_State);
return _Istr;
}
在示例 1 中,当您第三次调用时,函数必须以 because is on its own line 终止。这意味着 failbit 将在此处设置:getline()
_Changed = false;
^Z
if (!_Changed) {
_State |= _Myis::failbit;
}
与示例 2 一样,您不能在导致 的行中发送 EOF。这是因为分隔符会导致您在未到达 EOF 的情况下中断,并且 EOF 不能与 Windows 控制台中的非 EOF、非分隔符在同一行上发送。_Changed = true;
for (;; _Meta = _Istr.rdbuf()->snextc()) {
我的问题是:您可以使用 getline(std::cin, inp_str)
切换 std::cin eofbit
并通过 Windows 终端接口而不切换 std::cin
failbit
吗?
编辑
此代码演示了上述行为。
#include <iostream>
#include <string>
int main() {
while (!std::cin.eof()) {
std::string next_line;
std::getline(std::cin, next_line);
if (std::cin.eof()) {
std::cout << "EOF reached\n";
}
if (!std::cin) {
std::cout << "failbit set";
return 0;
}
}
return 0;
}
以示例 1 作为输入,此代码以 both 和 set 结尾。eofbit
failbit
使用示例 2 作为输入,此代码不会终止。
我这里有第二个密切相关的问题:
答: 暂无答案
评论