[英]Reading from input file
我在輸入文件中讀取時遇到問題。 輸入文件如下所示
萊昂內爾·梅西-10 43
費爾南多托雷斯9比29
克里斯蒂亞諾羅納爾多7 31
韋恩魯尼10 37
內馬爾17 29
Andres Iniesta 8 32
羅賓范佩西19 20
萊昂內爾·梅西10 43
哈維·埃爾南德斯6 36
MesutÖzil1038
Didier Drogba 10 35
費爾南多托雷斯9 29
卡卡10 17
問題是我不能使用getline函數,因為我想將名稱存儲到單個變量中以存儲到數組中,第一個數字存儲到變量中,第二個數字存儲到另一個變量中。 我也嘗試使用peek功能,但我從未學過它,所以我沒有成功。 如果有人知道如何閱讀直到名稱的結尾並將其存儲到一個非常值得贊賞的變量中。
這是我從輸入文件中讀取時的代碼
while(!fin.eof())
{
fin >> first >> last >> num >> point;
if (num > 0 && point > 0)
{
list[i].firstname = first;
list[i].lastname = last;
list[i].number = num;
list[i].points = point;
i++;
}
else if (num < 0 || point < 0)
{
reject[j].firstname = first;
reject[j].lastname = last;
reject[j].number = num;
reject[j].points = point;
j++;
}
}
如果輸入具有名字和姓氏,這將完美地工作。 我知道問題是關於鰭>>第一>>上一頁>>數字>>點;
但我不確定如何把第一個和最后一個(可能是中間)放在一起
你可以使用std::getline
來提取行,將行解析為std::vector
空格分隔的單詞。 然后你知道words.size() - 2
個單詞是名字的一部分。 例如:
std::fstream in("in.txt");
std::string line;
// Extract each line from the file
while (std::getline(in, line)) {
std::istringstream line_stream(line);
// Now parse line_stream into a vector of words
std::vector<std::string> words(std::istream_iterator<std::string>(line_stream),
(std::istream_iterator<std::string>()));
int name_word_count = words.size() - 2;
if (name_word_count > 0) {
// Concatenate the first name_word_count words into a name string
// and parse the last two words as integers
}
}
它看起來像你需要使用getline
,然后解析該行。 解析它的一個解決方案可能是在第一個數字之前拆分行,然后修剪前半部分,並將其用作名稱,並使用std::istringstream
解析std::istringstream
以讀取這兩個數字。 當然,如果某人有一個數字作為他們名字的一部分,這將失敗,但在我看來,這似乎是一個合法的限制。 換句話說,對於每一行,你會做:
std::string::iterator first_digit
= std::find_if( line.begin(), line.end(), IsDigit() );
if ( first_digit == line.end() ) {
// format error...
} else {
name = trim( std::string( line.begin(), first_digit ) );
std::istringstream parser( std::string( first_digit, line.end() ) );
parser >> firstNumber >> secondNumber >> std::ws;
if ( !parser || parser.get() != EOF ) {
// format error...
} else {
// Do what ya gotta do.
}
}
這樣的事情應該有效:
std::string str;
while(getline(infile, str))
{
std::string::size_type pos;
pos = str.find_last_of(' ');
if (pos == std::string::npos || pos < 1)
{
cout << "Something not right with this string: " << str << endl;
exit(1);
}
int last_number = stoi(str.substr(pos));
str = str.substr(0, pos-1); // Remove the number and the space.
pos = str.find_last_of(' ');
if (pos == std::string::npos || pos < 1)
{
cout << "Something not right with this string: " << str << endl;
exit(1);
}
int first_number = stoi(str.substr(pos));
str = str.substr(0, pos-1);
// str now contains the "name" as one string.
// ... here you use last_number and first_number and str to do what you need to do.
}
實際上,你可以使用getline(); 使用兩個參數方法,傳遞一個流和'\\ n'作為分隔符。
將整行分配為一個字符串,然后使用空格作為分隔符拆分字符串,並將后兩個轉換為整數。
1.)打開文件
std::ifstream myFile("somewhere.txt");
2.)檢查文件是否打開
if(myFile.is_open())
3.)讀取直到文件結束
while(!myFile.eof())
4.)將第一個名稱讀入名字數組
myFile >> firstName[numberOfPeople];
5.)將姓氏讀入姓氏數組
myFile >> lastName[numberOfPeople];
6.)將整數讀入整數數組
myFile >> integer[numberOfPeople];
7.)增加人數
numberOfPeople++;
8.)完成時,關閉文件
myFile.close();
9.)如果文件未打開,則報告錯誤。
else
std::cout << "\nFile did not open. " << std::endl;
您可以使用getline函數,只需解析字符串即可。 這可以使用strtok實現。
我已經為您的問題實施了解決方案(主要是為了我自己的學習)。 它按預期工作,但感覺有點冗長。
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<vector>
#include<algorithm>
#include<iterator>
struct PlayerData {
std::string name;
int number;
int points;
};
std::ostream& operator<<(std::ostream& os, const PlayerData& p) {
os<<"Name: "<<p.name<<", Number: "<<p.number<<", Points: "<<p.points;
return os;
}
PlayerData parse(const std::string& line) {
PlayerData data;
std::stringstream ss(line);
std::vector<std::string> tokens;
std::copy(std::istream_iterator<std::string>(ss),
std::istream_iterator<std::string>(),
std::back_inserter<std::vector<std::string>>(tokens));
data.points = std::stoi(tokens.at(tokens.size() - 1));
data.number = std::stoi(tokens.at(tokens.size() - 2));
for(auto it=tokens.begin(); it!=tokens.end()-2; ++it) {
data.name.append(" ");
data.name.append(*it);
}
return data;
}
int main(int argc, char* argv[]) {
std::string line;
std::vector<PlayerData> players;
{ // scope for fp
std::ifstream fp(argv[1], std::ios::in);
while(!fp.eof()) {
std::getline(fp, line);
if(line.size()>0) {
players.push_back(parse(line));
}
}
} // end of scope for fp
// print list of players, or do whatever you want with it.
for(auto p:players) {
std::cout<<p<<std::endl;
}
return 0;
}
使用支持C ++ 11的g ++版本編譯(在我的例子中是gcc 4.7.2)。
[Prompt] g++ -oparseline parseline.cpp -std=c++11 -O2
[Prompt] ./parseline players.txt
Name: Fernando Torres, Number: 9, Points: -29
Name: Cristiano Ronaldo, Number: 7, Points: 31
Name: Wayne Rooney, Number: 10, Points: 37
Name: Neymar, Number: 17, Points: 29
Name: Andres Iniesta, Number: 8, Points: 32
Name: Robin van Persie, Number: 19, Points: 20
Name: Lionel Messi, Number: 10, Points: 43
Name: Xavi Hernandez, Number: 6, Points: 36
Name: Mesut Özil, Number: 10, Points: 38
Name: Didier Drogba, Number: 10, Points: 35
Name: Fernando Torres, Number: 9, Points: 29
Name: Kaká, Number: 10, Points: 17
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.