[英]c++ getline() looping when used in file with a read in int array?
[英]Use getline and >> when read file C++
因為來自文件的數據如下所示:第1行是名稱(第一名),下一行是score(分數1分數2 .... score5),依此類推...因此,我認為我需要getline作為名稱和>>得分
數據文件示例
David Beckham
80 90 100 20 50
Ronaldinho Gaucho
99 80 100 20 60
....
首先,我有結構
struct Player {
string name;
int score[5];
} player[size]
從文件讀取數據時
int i = 0;
while(!file.eof())
{
for (int j = 0; j < 2; j++) //read each 2 two lines
{
if(j==0) // name
{
getline(file, player[i].name);
}
else if(j==1) // score
{
for(int k=0; k<5; k++) file >> player[i].grade[k];
}
}
i++; //move to next player
}
問題是看完(第一名球員)的所有分數后,似乎不去下一行繼續讀取下一個名字,那兒有點混亂。 因此,有什么建議可以糾正我的代碼或執行此操作的新想法?
讀取最后一個分數后,換行符仍位於輸入緩沖區上。 您需要跳過。 ignore
功能對此很有用。
getline(file, player[i].name);
for (int k = 0; k < 5; ++k)
file >> player[i].grade[k];
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
檢查適當的錯誤。 >>
運算符getline
和ignore
所有返回流引用,您可以檢查流引用是否成功。
不需要j
循環,因為每次迭代都做完全不同的事情。 只需立即編寫j=0
情況,然后緊跟j=1
情況,然后擺脫循環,就像上面的代碼一樣。 (請注意,循環內j
永遠不會等於2,因此無論如何您的條件都是錯誤的。)
您的主要問題是直接從流中讀取帶有>>的整數。 這與從流中讀取字符串相結合是一個壞主意。 讀取字符串將刪除新行,將顯示>>,不會刪除新行。
最好不要混合使用兩種形式。 始終使用>>或始終使用getline()。 注意:我說的不是最好的,我說的是最簡單的。 當您了解權衡因素以及如何補償其用法差異時,可以將它們一起使用。
因此,將數字行讀入字符串然后解析該字符串比較容易。
std::string lineOfNumbers;
std::getline(file, lineOfNumbers);
// Now you have read all the numbers and the new line.
std::stringstream streamOfNumbers(lineOfNumbers);
while(streamOfNumbers >> value)
{
// Do something with number.
}
使用幾乎總是錯誤的:
while(!file.eof())
這是因為直到您讀取了eof之后才設置EOF標志。 請注意,最后一次讀取將讀取直到但不會超過eof。 因此,即使沒有可用數據,您也將進入循環。
標准模式是:
while(file >> object)
{
// Action
}
考慮到這一點,我將定義一個代表您想要的所有信息的類(即兩行)。 一個簡單的版本是
class TwoLineReader
{
public:
std::string line1;
std::string line2;
};
std::istream& operator>>(std::istream& stream, TowLineReader& record)
{
std::getline(stream, record.line1);
std::getline(stream, record.line2);
return stream;
}
TowLineReader obj;
while(file >> obj)
{
// Do stuff
}
如果您只想讀取行,這很好。
但是數據看起來好像具有結構。 因此,我將構造一個表示數據的類,然后將數據直接讀取到該結構中。 所以這是我會做的更多的事情。 我還將用算法替換while()循環。
頭
#include <algorithm>
#include <iterator>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
/*
* Example Data
David Beckham
80 90 100 20 50
Ronaldinho Gaucho
99 80 100 20 60
*/
班級:
class Player
{
std::string name;
std::vector<int> goals;
// Stream operator that reads a platers name and his goals.
friend std::istream& operator>>(std::istream& stream, Player& record)
{
// Read the name
std::getline(stream, record.name);
// Read the line of goals.
// Copies the data into goals.
std::string scores;
std::getline(stream, scores);
// std::copy replaces a while loop that pushes each number into the vector.
std::stringstream scorestream(scores);
std::copy( std::istream_iterator<int>(scorestream),
std::istream_iterator<int>(),
std::back_inserter(record.goals));
return stream;
}
};
用法:
int main()
{
std::ifstream dataFile("data");
std::vector<Player> players;
// Copy all players into a vetor
std::copy( std::istream_iterator<Player>(dataFile),
std::istream_iterator<Player>(),
std::back_inserter(players));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.