将未知数量的后跟双精度数的字符串读入vector
Reading unknown number of strings followed by doubles into a vector
所以,我想要打开一个包含足球队名称的文件,后面跟着其他数据。例如:
Leicester City 38 12 13
West Ham 38 14 15
Schalke04 40 16 17
然后,我将该数据读入对象类型的向量(我有"Team.h")。问题是,有些球队的名字只有1个字符串,有些则有2个或更多,有些甚至在名字中有数字(如schalke04)。那么,我如何打开一个文件,并正确地读取矢量信息?
#ifndef TEAM_H
#define TEAM_H
#include <string>
using namespace std;
class Team
{
public:
Team();
Team(string, double, double, double);
string getName();
double getn1();
double getn2();
double getn3();
private:
string name;
double n1;
double n2;
double n3;
};
#endif
Team.cpp
#include "Team.h"
Team::Team()
{
}
Team::Team(string n, double N1, double N2, double N3)
{
name = n;
n1 = N1;
n2 = n2;
n3 = N3;
}
string Team::getName()
{
return name;
}
double Team::getn1()
{
return n1;
}
double Team::getn2()
{
return n2;
}
double Team::getn3()
{
return n3;
}
通常在vector中读入像这样
inFile >> name >> n1 >> n2 >> n3;
Team newTeam(name, n1, n2, n3);
teams.push_back(newTeam) //vector<Team>teams declared earlier
UPD:My search method(not good)
string homeTeam;
Team ht;
for (Team team: newTeams)
{
if(team.getName() == homeTeam)
{
ht = team;
}
}
如果您可以更改Team.h
和Team.cpp
,请考虑添加
friend istream &operator>>(istream &input, Team &t);
friend ostream &operator<<(ostream &output, Team &t);
从输入流读取数据到Team
类的对象,并将整个对象输出到输出流。
我的意思是:
Team.h
#ifndef TEAM_H
#define TEAM_H
#include <string>
using namespace std;
class Team
{
public:
Team();
Team(string, double, double, double);
string getName();
double getn1();
double getn2();
double getn3();
friend istream &operator>>(istream &input, Team &t);
friend ostream &operator<<(ostream &output, Team &t);
private:
string name;
double n1;
double n2;
double n3;
};
#endif
Team.cpp(仅根据相关问题的答案添加新行)
istream &operator>>(istream &input, Team &t)
{
while (!input.eof() && input.good())
{
string s;
string name;
getline(input, s);
if (input.bad() || s.length() == 0)
{
input.setstate(ios::badbit); // for case of empty line
return input;
}
istringstream ss(s);
string str;
bool notNumber;
do{
ss >> t.n1;
notNumber = ss.fail();
if (notNumber)
{
ss.clear();
ss >> str;
//if(name.length() > 0) name.append(" "); // uncomment this if you want spaces in name
name.append(str);
}
} while (notNumber && !ss.eof());
if (name.length() == 0)
continue;
t.name = name;
if (notNumber)
{
input.setstate(ios::badbit);
return input;
}
ss >> t.n2;
ss >> t.n3;
if (ss.fail())
{
input.setstate(ios::badbit);
return input;
}
return input;
}
return input;
}
ostream &operator<<(ostream &output, Team &t)
{
output << t.getName() << " " << t.getn1() << " " << t.getn2() << " " << t.getn3();
return output;
}
用法如下:
// reading data from file
vector<Team> dataTable;
while (!inFile.eof() && !inFile.bad())
{
Team tmp;
inFile >> tmp;
if (!inFile.fail())
dataTable.push_back(tmp);
else
inFile.clear();
}
// print data stored in table
for (vector<Team>::iterator i = dataTable.begin(); i != dataTable.end(); i++)
{
cout << *i << endl;
}
分而治之
将相对复杂的任务分成两个或多个较小的任务。然后执行每一个小任务。每一个小任务都应该比原来的任务更容易。在完成了每一个小任务之后,你就完成了原来的任务。
你的第一步是阅读每个队伍及其得分。输入文件的每一行都给出了这些信息。所以,你的第一个小任务是阅读一个团队的信息价值,一次:
std::string teaminfo;
while (std::getline(std::cin, teaminfo).good())
{
// Here be dragons.
}
"here be dragons"部分是您将读取teaminfo
中的单行文本并对其进行解析的地方。这将是下一个任务,但重点是你现在已经完成了第一个较小的任务:读取一个团队的得分值。现在已经完成了。现在,您需要弄清楚如何提取所需的单个数据块。这将是"here be dragons"部分。
根据我对问题的理解,每行字符串上的最后三项信息是三个分数,由空格分隔。在此之前,其他所有内容都是该队的名称。
因此,当前的任务是从行中删除最后三个以空格分隔的值。这也是一项相对复杂的任务。因此,它也需要被分割,并作为几个独立的小任务来征服。
首要任务是删除读取行末尾的任何无关的空白。您没有指出是否可能在行尾有尾随空格。如果没有,可以省略此步骤。但是,如果需要删除末尾的空白,让我们这样做:
while (!teaminfo.empty() && teaminfo[teaminfo.size()-1] == ' ')
teaminfo=teaminfo.substr(0, teaminfo.size()-1);
一个相当粗糙的方法,但它已经足够好了。因此,现在尾部的空白已经被修剪。
好,那么剩下的任务就是删除行上的最后三个值。我们再除以这个。让我们从编写一个函数开始,它从行中删除最后一个值,并返回它:
std::string removeLastValue(std::string &line)
{
size_t p=line.rfind(' ');
std::string word;
if (p == std::string::npos) // Edge case, last word.
{
p=0;
word=line;
}
else
{
word=line.substr(p+1);
}
while (p > 0 && line[p-1] == ' ')
--p;
line=line.substr(0, p);
return word;
}
您没有明确当行太短且不包含三个分数的球队名称时,您的预期输入结果是什么。在这里,错误的输入导致返回一个空字符串。
无论如何,最后一个空格之后的所有内容都被提取到word
;然后,快速循环在line
中最后一个单词之前的空格上进行备份,并将line
修剪到该点。我们做完了。
剩下需要完成的任务现在是微不足道的:调用这个函数三次以从teaminfo
字符串中删除最后三个值。很明显,剩下的是你们队的名字。此外,每个删除的单词都是std::string
,您只需将每个单词转换为double
。
这是你应该能够自己做的事情,我不需要写出来
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 有没有办法将字符串添加到 Vector 中,但前提是它尚不存在?->C++
- 连接和压缩标准::vector<std::字符串的最佳方法>
- C++ 无法将 std::vector<BYTE> 转换为字符串或字符数组
- 如何在C++中处理多维字符串 VECTOR 的字符?
- 如何检查 std::vector<std::string> 的元素是否以某个子字符串开头?
- "error: subscripted value is not an array, pointer, or vector",我正在使用字符串
- 从 vector<pair<string, int 中提取不包含 0 的字符串>>
- 如何确定字符串是否包含在 std::vector 的任何字符串中
- 检查一系列单词,形成一个文本文件,保存在字符串vector C 中
- 仅威胁唯一字符串 - 什么是更快的 vector<std::string> 或只是 std::string
- 检查 std::vector 中的字符串是否包含C++中的子字符串
- 如何将十六进制字符串分为std :: vector
- STD :: vector和std ::字符串重新分配策略
- C++ vector 中不存在的字符串成员变量
- cout错误地打印出字符串的Vector
- 无法将C风格的字符串推送到std::vector中
- std::vector中的字符串验证
- 将 vector<unsigned char> {1,2,3} 转换为字符串"1-2-3" AS DIGITS
- 使用旧的c++编译器查找字符串Vector的索引