从用换行符和逗号分隔的txt文件中读取
Read from txt file delimited by newlines and commas
我试图从一个txt文件中读取信息,但有些问题没有解决。我需要读取每一行,并将其保存在属于类Bilhete的变量中。
Alexandre
20/12/2015
1,2,3,4
Luis
30/10/1990
3,4,5,6
这是我的txt。
这代表一张票(葡萄牙语为bilhette):-所有者名称-过期日期-我可以参加的比赛。每个数字代表比赛的id。我的项目中有一门竞赛课,但我认为这对这个问题不是很重要
void Campeonato::readFileBilhetes(string filename) {
ifstream ficheiro_leitura(filename.c_str());
vector<Prova*> vecprovas = calendario->getProvas();
vector <int> indices; //vector with competitions id
if(!ficheiro_leitura)
throw ErroNoFicheiro(filename);
else{
string dono, data, provasNoBilhete, vendido; //owner, date, competitions in the ticket,
while (!ficheiro_leitura.eof()){
getline(ficheiro_leitura, dono);
getline(ficheiro_leitura, data);
getline(ficheiro_leitura, provasNoBilhete);
stringstream dataSs;
date d;
dataSs << data;
int dia, mes, ano; //day, month, //year
char tmp;
dataSs >> dia >> tmp >> mes >> tmp >> ano;
if(dia < 1 || dia > 31|| mes < 1 || mes > 12 || ano < 1 || (dia > 28 && mes == 2) || (dia > 30 && mes == 4) || (dia > 30 && mes == 6) || (dia > 30 && mes == 9) || (dia > 30 && mes == 11)){
cout << "Data invalida!";
}
else{
d.dia = dia; //day
d.mes = mes; //month
d.ano = ano; //year
}
string s1 = "";
string s2= "";
stringstream provasS;
int i = 0;
while (provasNoBilhete[i] != 'n' && provasNoBilhete[i] != ' '){
if(provasNoBilhete[i] == ','){
int indice;
provasS.clear();
provasS.str("");
provasS.str(s2);
provasS >> indice;
indices.push_back(indice);
}
else
provasS << provasNoBilhete[i];
++i;
Bilhete *bi1 = new Bilhete(d, dono, indices);
inserirBilhete(*bi1); //insert
}
}
}
}
如何正确保存这些值?
向致以最良好的问候
我不确定您在读取文件时到底遇到了什么值的问题,但这里有一个示例,展示了如何读取您试图获得的值。这将正确地将名称读入字符串,将日期读入单独的整数,并将竞争id读入整数向量。我发现使用iss.peek
方法对调试stringstream
的非常有帮助。在这里,你可以看到我正在使用这个方法来确保我正在读取一个有效的文件。
另外,正如Beta所说,我建议不要使用file.eof()
。尝试在循环的条件中使用getline
。
fstream infile(file);
string linha, dono;
int dia, mes, ano;
vector<int> campeonatoIds;
while (getline(infile, dono)) // get name and check status file stream
{
cout << dono << endl;
// read in date
getline(infile, linha);
int tmp;
istringstream iss (linha);
iss >> dia;
if (iss.peek() != '/')
{
cerr << "incorrectly formatted file" << endl;
exit(EXIT_FAILURE);
}
iss.ignore();
iss >> mes;
if (iss.peek() != '/')
{
cerr << "incorrectly formatted file" << endl;
exit(EXIT_FAILURE);
}
iss.ignore();
iss >> ano;
cout << dia << "/" << mes << "/" << ano << endl;
// read in competition ids
getline(infile, linha);
istringstream iss2(linha);
while (iss2.peek() != ',' && iss2.good())
{
iss2 >> tmp;
cout << tmp << ",";
campeonatoIds.push_back(tmp);
iss2.ignore();
}
cout << endl;
}
但是,我个人认为在这种情况下使用getline
比使用stringstream
更容易、更干净。以下是重构为使用getline
的相同代码。
fstream infile(file);
string linha, dono;
int dia, mes, ano;
vector<int> campeonatoIds;
while (getline(infile, dono)) // get name and check status file stream
{
cout << dono << endl;
// read in date
getline(infile, linha);
istringstream iss (linha);
string tmpstr1;
getline(iss, tmpstr1, '/');
dia = atoi(tmpstr1.c_str());
getline(iss, tmpstr1, '/');
mes = atoi(tmpstr1.c_str());
getline(iss, tmpstr1, '/');
ano = atoi(tmpstr1.c_str());
cout << dia << "/" << mes << "/" << ano << endl;
// read in competition ids
getline(infile, linha);
istringstream iss2(linha);
string tmpstr2;
while (getline(iss2, tmpstr2, ','))
{
campeonatoIds.push_back(atoi(tmpstr2.c_str()));
}
for (auto it : campeonatoIds)
{
cout << it << ",";
}
cout << endl;
campeonatoIds.clear();
}
正如您所看到的,我在while循环中使用getline
而不使用,这允许您检查文件的有效性。此外,我认为使用getline
可以为文件流的简单分离提供一个可选的分隔符。
我首先会为ticket
类重载operator>>
,这样它就有了读取单个票证的主体。然后我会用那个操作符从流中读取门票。
该标准已经定义了一个get_tgime
(和put_time
)操纵器,用于将时间从流读取到struct tm
中,因此我们不妨使用它们。
代码可能看起来像这样:
friend std::istream &operator>>(std::istream &is, ticket &t) {
std::getline(is, t.name);
is >> std::get_time(&t.date, " %d / %m / %Y ");
std::string temp;
std::getline(is, temp);
t.events = parse_list<int>(temp);
return is;
}
parse_list
将是这个一般顺序上的东西:
template <class T>
std::vector<T> parse_list(std::string const &in) {
T temp;
std::vector<T> ret;
std::istringstream buf(in);
while (buf >> temp) {
ret.push_back(temp);
buf.ignore(1);
}
return ret;
}
有了这些定义,读取一个充满ticket
数据的文件并将其全部放入vector
中会看起来像这样:
std::vector<ticket> tickets { std::istream_iterator<ticket>(input),
std::istream_iterator<ticket>() };
- 如何将 txt 文件中的行分隔为组件C++
- 无法打开.txt文件
- 如何使用CLion在Mac上创建一个新的.txt文件
- 使用fstream对txt文件中的数字进行循环
- Visual Studio在尝试读取resource.txt文件时崩溃
- 如何从txt文件中读取多个不同长度的数组?
- 在一次迭代中从 txt 文件中读取多行
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?
- 写入超过 1GB 的.txt文件时出现奇怪的行为
- 视觉 如何循环访问C++中遵循类似格式的多个.txt文件?
- txt 文件中浮点数的最大和最小值
- 从.txt文件中读取浮点型数字并在公式中使用它们
- C++将文本从.txt文件解析为变量
- 在树结构.txt文件中搜索节点
- 为什么我无法打开/读取从 Python 调用的 C 扩展名中的 txt 文件?
- 在 txt 文件中显示前两个数字的程序
- 如何从具有两列的.txt文件创建并行数组?
- 如何使用c ++读取带有非英文字母的*.txt文件?(国际化)
- 如何像在 C++ 中处理数组一样对 .txt 文件中的字符进行寻址?
- 如何读取 TXT 文件并仅将 int 存储在 C 中