Why does reading a record struct fields from std::istream fail, and how can I fix it?

后端 未结 9 2303
野性不改
野性不改 2020-11-21 11:40

Suppose we have the following situation:

  • A record struct is declared as follows

struct Person {
    unsigned int id;
    std::st         


        
9条回答
  •  迷失自我
    2020-11-21 12:10

    Here's an implementation of a manipulator I came up with that counts the delimiter through each extracted character. Using the number of delimiters you specify, it will extract words from the input stream. Here's a working demo.

    template
    struct word_inserter_impl {
        word_inserter_impl(std::size_t words, std::basic_string& str, charT delim)
            : str_(str)
            , delim_(delim)
            , words_(words)
        { }
    
        friend std::basic_istream&
        operator>>(std::basic_istream& is, const word_inserter_impl& wi) {
            typename std::basic_istream::sentry ok(is);
    
            if (ok) {
                std::istreambuf_iterator it(is), end;
                std::back_insert_iterator dest(wi.str_);
    
                while (it != end && wi.words_) {
                    if (*it == wi.delim_ && --wi.words_ == 0) {
                        break;
                    }
                    dest++ = *it++;
                }
            }
            return is;
        }
    private:
        std::basic_string& str_;
        charT delim_;
        mutable std::size_t words_;
    };
    
    template
    word_inserter_impl word_inserter(std::size_t words, std::basic_string& str, charT delim = charT(' ')) {
        return word_inserter_impl(words, str, delim);
    }
    

    Now you can just do:

    while (ifs >> actRecord.id >> word_inserter(2, actRecord.name) >> actRecord.age) {
        std::cout << actRecord.id << " " << actRecord.name << " " << actRecord.age << '\n';
    }
    

    Live Demo

提交回复
热议问题