How to read integers elegantly using C++ stream?

后端 未结 6 1282
醉话见心
醉话见心 2021-01-02 08:52

I have a file full of lines in this format:

1 - 2: 3

I want to only load numbers using C++ streams. Whats the most elegant way to do it? I

6条回答
  •  说谎
    说谎 (楼主)
    2021-01-02 09:15

    You can use a locale to change what things are read from the file as it is being read. That is, you will filter out all non-numeric values:

    struct numeric_only: std::ctype 
    {
        numeric_only(): std::ctype(get_table()) {}
    
        static std::ctype_base::mask const* get_table()
        {
            static std::vector 
                rc(std::ctype::table_size,std::ctype_base::space);
    
            std::fill(&rc['0'], &rc[':'], std::ctype_base::digit);
            return &rc[0];
        }
    };
    
    std::fstream myFile("foo.txt");
    myfile.imbue(std::locale(std::locale(), new numeric_only()));
    

    Then when you read your file, it'll convert all non digits to spaces while leaving you only the numbers. After that, you can simply use your normal conversions to transform what is being read into ints.

    std::vector intFromFile;
    std::istream_iterator myFileIter(myFile);
    std::istream_iterator eos;
    std::copy(myFileIter, eos, std::back_inserter(intFromFile));
    

    Response to the comments below:

    Here is what I did to get it to work

    int main(int args, char** argv){
        std::fstream blah;
        blah.open("foo.txt", std::fstream::in);
        if(!blah.is_open()){
            std::cout << "no file";
            return 0;
        }
        blah.imbue(std::locale(std::locale(), new numeric_only()));
    
        std::vector intFromFile;
        std::istream_iterator myFileIter(blah);
        std::istream_iterator eos;
        std::copy(myFileIter, eos, std::back_inserter(intFromFile));
    
       return 0;
    }
    

    And this put only the ints into the vector, nothing more, nothing less. The reason it wasn't working before was two fold:

    1. I was filling up to '9' but not '9' itself. I've changed the fill to ':'
    2. Numbers larger than what an int can hold are a problem. I'd suggest using longs.

提交回复
热议问题