简体   繁体   English

如何在不读取格式化输入的情况下在istream上设置EOF?

[英]How do I set EOF on an istream without reading formatted input?

I'm doing a read in on a file character by character using istream::get(). 我正在使用istream :: get()逐个字符读取文件。 How do I end this function with something to check if there's nothing left to read in formatted in the file (eg. only whitespace) and set the corresponding flags (EOF, bad, etc)? 如何用某种东西结束此功能,以检查是否没有剩余要读取的文件格式(例如,仅空白)并设置相应的标志(EOF,坏等)?

You can strip any amount of leading (or trailing, as it were) whitespace from a stream at any time by reading to std::ws . 通过读取std::ws ,您可以随时从流中删除任何数量的前导(或结尾)空格。 For instance, if we were reading a file from STDIN, we would do: 例如,如果我们正在从STDIN读取文件,则将执行以下操作:

std::cin >> std::ws

Credit to this comment on another version of this question, asked four years later. 归功于四年后提出的对该问题的另一个版本的评论

Construct an istream::sentry on the stream. 在流上构造一个istream::sentry This will have a few side effects , the one we care about being: 这会有一些副作用 ,我们关心的是:

If its skipws format flag is set, and the constructor is not passed true as second argument ( noskipws ), all leading whitespace characters (locale-specific) are extracted and discarded. 如果设置了skipws格式标志,并且未将构造函数作为第二个参数传递给truenoskipws ), 则将提取并丢弃所有前导空白字符 (特定于语言环境的字符 )。 If this operation exhausts the source of characters, the function sets both the failbit and eofbit internal state flags 如果此操作耗尽了字符源,则该函数将同时设置failbiteofbit 内部状态标志

How do I end this function with something to check if there's nothing left to read in formatted in the file (eg. only whitespace)? 如何用某种东西来结束此功能,以检查文件中是否没有剩余要读取的格式(例如,仅空格)?

Whitespace characters are characters in the stream. 空格字符是流中的字符。 You cannot assume that the stream will do intelligent processing for you. 您不能假定流将为您执行智能处理。 Until and unless, you write your own filtering stream. 直到并且除非您编写自己的过滤流。

By default, all of the formatted extraction operations (overloads of operator>>() ) skip over whitespace before extracting an item -- are you sure you want to part ways with this approach? 默认情况下,所有格式化的提取操作( operator>>()重载operator>>() 提取项目之前都会跳过空格-您确定要分摊此方法吗?

If yes, then you could probably achieve what you want by deriving a new class, my_istream , from istream , and overriding each operator>>() to call the following method at the end: 如果是,那么您可以通过从istream派生一个新类my_istream并覆盖每个operator>>()来在最后调用以下方法来实现所需的目标:

void skip_whitespace() {
    char ch;
    ios_base old_flags = flags(ios_base::skipws);
    *this >> ch;    // Skips over whitespace to read a character
    flags(old_flags);

    if (*this) {    // I.e. not at end of file and no errors occurred
        unget();
    }
}

It's quite a bit of work. 这是很多工作。 I'm leaving out a few details here (such as the fact that a more general solution would be to override the class template basic_istream<CharT, Traits> ). 我在这里省略了一些细节(例如,更通用的解决方案是重写类模板basic_istream<CharT, Traits> )。

istream is not going to help a lot - it functions as designed. istream不会有太大帮助-它按设计运行。 However, it delegates the actual reading to streambufs. 但是,它将实际读取委托给streambufs。 If your streambuf wrapper trims trailing whitespace, an istream reading from that streambuf won't notice it. 如果您的streambuf包装器修剪了结尾的空白,则从该streambuf读取的istream读数将不会引起注意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM