Reading integers from a file with mixed integers, letters, and spaces C++

余生颓废 提交于 2020-01-16 18:48:29

问题


This is a sort of self-imposed extra credit problem I'm adding to my current programming assignment which I finished a week early. The assignment involved reading in integers from a file with multiple integers per line, each separated by a space. This was achieved easily using while(inFile >> val) .

The challenge I put myself up to was to try and read integers from a file of mixed numbers and letters, pulling out all contiguous digits as separate integers composed of those digits. For examples if I was reading in the following line from a text file:

12f 356 48 r56 fs6879 57g 132e efw ddf312 323f

The values that would be read in (and stored) would be

12f 356 48 r56 fs6879 57g 132e efw ddf312 323f

or

12, 356, 48, 56, 6879, 57, 132, 312, and 323

I've spent all afternoon digging through cplusplus.com and reading cover to cover the specifics of get, getline, cin etc. and I am unable to find an elegant solution for this. Every method I can deduce involves exhaustive reading in and storing of each character from the entire file into a container of some sort and then going through one element at a time and pulling out each digit.

My question is if there is a way to do this during the process of reading them in from a file; ie does the functionality of get, getline, cin and company support that complex of an operation?


回答1:


Read one character at a time and inspect it. Have a variable that maintains the number currently being read, and a flag telling you if you are in the middle of processing a number.

If the current character is a digit then multiple the current number by 10 and add the digit to the number (and set the "processing a number" flag).

If the current character isn't a digit and you were in the middle of processing a number, you have reached the end of the number and should add it to your output.

Here is a simple such implementation:

std::vector<int> read_integers(std::istream & input)
{
    std::vector<int> numbers;

    int number = 0;
    bool have_number = false;

    char c;

    // Loop until reading fails.
    while (input.get(c)) {
        if (c >= '0' && c <= '9') {
            // We have a digit.
            have_number = true;

            // Add the digit to the right of our number.  (No overflow check here!)
            number = number * 10 + (c - '0');
        } else if (have_number) {
            // It wasn't a digit and we started on a number, so we hit the end of it.
            numbers.push_back(number);
            have_number = false;
            number = 0;
        }
    }

    // Make sure if we ended with a number that we return it, too.
    if (have_number) { numbers.push_back(number); }

    return numbers;
}

(See a live demo.)

Now you can do something like this to read all integers from standard input:

std::vector<int> numbers = read_integers(std::cin);

This will work equally well with an std::ifstream.

You might consider making the function a template where the argument specifies the numeric type to use -- this will allow you to (for example) switch to long long int without altering the function, if you know the file is going to contain large numbers that don't fit inside of an int.



来源:https://stackoverflow.com/questions/26151288/reading-integers-from-a-file-with-mixed-integers-letters-and-spaces-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!