从输入文件中读取
Reading from input file
我在读取输入文件时遇到麻烦。输入文件如下所示
梅西-10 - 43
托雷斯9 -29
c罗7 31
韦恩·鲁尼10/37
内马尔17/29
伊涅斯塔8 32
范佩西19 20
梅西10/43
哈维·埃尔南德斯6/36
Mesut Özil 10 38
德罗巴10分35秒
费尔南多·托雷斯9/29
kak
问题是我不能使用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++;
}
}
如果输入有姓和名,则可以完美地工作。我知道问题是在Fin>> first>> last>> num>> point;
但我不确定如何把第一个和最后一个(可能是中间)在一起
您可以使用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::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。)当while完成时,关闭file
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
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 读取文件的最后一行并输入到链接列表时出错
- 为什么在读取文件大小时文件IO速度会发生变化
- 读取文件时运行时的未知行为
- 如何逐行读取文件,每行中的内容都用空格分隔并将其写入新文件中
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- C++ 读取文件读取文件不正确
- 读取文件并将其存储在unordered_map中时出现问题
- 读取文件时无法使用 OpenMP 获得加速
- 使用istringstearm和get行缓慢读取文件
- 如何继续读取不同功能中的文件,而不是从头开始再次读取文件?
- 读取文件时引发异常
- 从标准输入读取文件后读取用户输入
- 在读取文件后重置句柄
- 如何在C++编译时读取文件?
- std::ifstream 在读取文件中最后一项时设置 eofbit,但仅在读取数值类型时发生
- 读取文件在第二次调用时返回INVALID_HANDLE
- 通过指针读取文件
- 逐行读取文件,并将数据插入变量和数组中