简体   繁体   中英

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(). 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)?

You can strip any amount of leading (or trailing, as it were) whitespace from a stream at any time by reading to std::ws . For instance, if we were reading a file from STDIN, we would do:

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. 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. If this operation exhausts the source of characters, the function sets both the failbit and eofbit internal state flags

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?

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:

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> ).

istream is not going to help a lot - it functions as designed. However, it delegates the actual reading to streambufs. If your streambuf wrapper trims trailing whitespace, an istream reading from that streambuf won't notice it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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