how to read and parse text files with istringstream?

♀尐吖头ヾ 提交于 2021-01-29 08:05:00

问题


I am trying to read a .txt file line by line:

vector<vector<int>> iVecGrid;
vector<int> iVecRow;

ifstream text;
text.open("grid.txt", ios::in);

if (!text)
{
    cout << "Error!\n";
    return EXIT_FAILURE;
}

istringstream isLine;
string sLine;
while (getline(text, sLine))
{
    isLine.str(sLine);
    int iNumber;
    while (isLine >> iNumber)
    {
        cout << iNumber << " ";
        iVecRow.push_back(iNumber);
    }
    cout << endl;

    iVecGrid.push_back(iVecRow);
    iVecRow.clear();
}

When I put isLine inside the while (getline(text, sLine)) loop, it works fine.

But when I put it outside, it bugged out for some reason.

.txt file:

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48

回答1:


When you are done with the following loop

while (isLine >> iNumber)
{
    cout << iNumber << " ";
    iVecRow.push_back(iNumber);
}

isLine is in a state of error. The error state needs to cleared. Add the following line after the loop.

isLine.clear();

Also, the position of isLine needs to be reset to point to the start of the string. You can use the following line for that.

isLine.seekg(0);

Both of these problems are avoided by moving the scope of isLine to inside the while block.

The following should work.

while (getline(text, sLine))
{
    isLine.str(sLine);
    isLine.seekg(0);   //ADD. Start reading from position 0.

    int iNumber;
    while (isLine >> iNumber)
    {
        cout << iNumber << " ";
        iVecRow.push_back(iNumber);
    }

    isLine.clear();  //ADD. Clear the error state.

    cout << endl;

    iVecGrid.push_back(iVecRow);
    iVecRow.clear();
}

However, I would recommend sticking to your first approach. It removes the unnecessary clutter from your code.

while (getline(text, sLine))
{
    std::istringstream isLine(sLine);

    int iNumber;
    while (isLine >> iNumber)
    {
        cout << iNumber << " ";
        iVecRow.push_back(iNumber);
    }

    cout << endl;

    iVecGrid.push_back(iVecRow);
    iVecRow.clear();
}



回答2:


When you do

while (isLine >> iNumber)
{
    cout << iNumber << " ";
    iVecRow.push_back(iNumber);
}

the loop runs until isLine enters a failed state. Once it enters that failed state, you can no longer read from it until you call the clear member function to clear those errors. This means that when isLine is declare outside of the while loop, the first iteration of the loop puts it into an error state, and it stays that way for each subsequent iteration since you do not manually clear the errors.

On the other hand, when isLine is declared inside the while loop, it is destroyed at the end of the loop and created again at the start of the next iteration. This process gives you a new stream that is not in a error state so you can use it as expected.



来源:https://stackoverflow.com/questions/62522922/how-to-read-and-parse-text-files-with-istringstream

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