我想阅读自定义文件结构并输出它们,我也想忽略格式不正确的行。例如评论,标题等,
我已经尝试过此代码,但是当遇到遇到超出结构的行时,它将停止循环。
这是txt文件。
1001 Promod Dinal IT-K20 42 42
1002 Sahan Navod BM-K11 65 28
day_02
1003 Kaushani Dilinika BM-K12 69 49
1004 Fathima Sahana QS-K14 73 43
int main()
{
ifstream thefile;
thefile.open("GameZone.txt");
int id;
char fName[30];
char lName[30];
char stream[30];
int score;
int time;
if (!thefile.is_open()) {
cout << "cant open the file" << endl;
}
else {
while (!thefile.eof()) {
if (thefile >> id >> fName >> lName >> stream >> score >> time) {
cout << id << " ," << fName << " ," << lName << " ," << stream << " ," << score << " ," << time << endl;
}else if(!(thefile >> id >> fName >> lName >> stream >> score >> time)){
cout << "skip the row" << endl;
continue;
}
}
}
return 0;
}
输出
1001 ,Promod ,Dinal ,IT-K20 ,42 ,42
1002 ,Sahan ,Navod ,BM-K11 ,65 ,28
答案 0 :(得分:4)
请勿尝试直接从文件中解析字段。而是,从文件中读取行并尝试解析这些行。使用以下算法:
答案 1 :(得分:0)
如果您仍然难以实现,那么一个非常简单的实现将简单地读取每一行,在该行中创建一个stringstream
以允许您尝试从中解析值,然后根据结果进行解析从stringstream
读取的结果以您的(相当奇怪的" ,"
)csv格式输出值,或者直接阅读下一行并重试。
您应该使用std::string
而不是char[]
将字符串数据保存在C ++中。两者都可以使用,但是后者更加用户友好和灵活。无论哪种情况,您都需要协调构成struct
的一条记录的所有不同类型的数据。如果您实际要做的不仅仅是将数据转储到stdout
,这将带来很多好处。例如,您可以将所有读取的数据存储在std::vector
结构中,然后可以进一步处理数据(例如sort
,push_back
或erase
记录),或将其传递给其他功能进行进一步处理。
使用int
和std::string
的简单结构可能是:
struct record_t { /* simple struct to coordinate data in single record */
int id, score, time;
std::string fname, lname, stream;
};
以csv格式读取和输出记录,可以像使用临时结构一样简单地尝试将行解析为行,如果成功,则可以根据需要输出(或进一步使用)数据,例如>
std::string line; /* string to hold line */
std:: ifstream fin (argv[1]); /* in stream for file */
while (getline (fin, line)) { /* read entire line into line */
std::stringstream ss (line); /* create stringstream from line */
record_t record; /* temp struct to read into */
if (ss >> record.id >> record.fname >> record.lname >>
record.stream >> record.score >> record.time)
/* if successful read from stringstream, output record */
std::cout << record.id << " ," << record.fname << " ,"
<< record.lname << " ," << record.stream << " ,"
<< record.score << " ," << record.time << '\n';
}
在将文件作为程序的第一个参数读取的简短示例中,完全将其放入:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
struct record_t { /* simple struct to coordinate data in single record */
int id, score, time;
std::string fname, lname, stream;
};
int main (int argc, char **argv) {
if (argc < 2) { /* validate at least 1 argument provided */
std::cerr << "error: filename required.\n";
return 1;
}
std::string line; /* string to hold line */
std:: ifstream fin (argv[1]); /* in stream for file */
while (getline (fin, line)) { /* read entire line into line */
std::stringstream ss (line); /* create stringstream from line */
record_t record; /* temp struct to read into */
if (ss >> record.id >> record.fname >> record.lname >>
record.stream >> record.score >> record.time)
/* if successful read from stringstream, output record */
std::cout << record.id << " ," << record.fname << " ,"
<< record.lname << " ," << record.stream << " ,"
<< record.score << " ," << record.time << '\n';
}
}
(注意:请勿硬编码文件名或在代码中使用魔术数字)
使用/输出示例
以比较奇怪的" ,"
csv格式输出:
$ ./bin/readrecords dat/records.txt
1001 ,Promod ,Dinal ,IT-K20 ,42 ,42
1002 ,Sahan ,Navod ,BM-K11 ,65 ,28
1003 ,Kaushani ,Dilinika ,BM-K12 ,69 ,49
1004 ,Fathima ,Sahana ,QS-K14 ,73 ,43
要使事情更有用,可以将所有记录存储在std::vector<record_t>
(结构向量)中,而不是直接直接输出记录。这样就可以进一步处理您的数据。看看您是否可以理解下面关于每个记录如何存储在向量中的更改,然后使用Range-based for loop循环遍历向量中保存的每个记录以输出您的信息。
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
struct record_t { /* simple struct to coordinate data in single record */
int id, score, time;
std::string fname, lname, stream;
};
int main (int argc, char **argv) {
if (argc < 2) { /* validate at least 1 argument provided */
std::cerr << "error: filename required.\n";
return 1;
}
std::string line; /* string to hold line */
std:: ifstream fin (argv[1]); /* in stream for file */
std::vector<record_t> records; /* vector of records */
while (getline (fin, line)) { /* read entire line into line */
std::stringstream ss (line); /* create stringstream from line */
record_t record; /* temp struct to read into */
if (ss >> record.id >> record.fname >> record.lname >>
record.stream >> record.score >> record.time)
records.push_back(record); /* if good read, add to vector */
}
if (records.size() > 0) /* validate vector contains records */
for (auto& r : records) /* loop over all records */
std::cout << r.id << " ," << r.fname << " ," << r.lname << " ,"
<< r.stream << " ," << r.score << " ," << r.time << '\n';
else /* if no records read, throw error */
std::cerr << "error: no records read from file.\n";
}
仔细检查一下,如果还有其他问题,请告诉我。