问题
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