我目前正在研究一个应该从文本文件中读取数据的程序,并将所述数据放在链表中。我对我正在做的事情有了很好的了解,但问题是,如果数据格式中存在任何错误,我应该包含错误处理,跳转到下一行。文件。
该文件包含有关模型形式及其序列号的多个终结器的信息。
可以读取的数据示例如下:
TERMINATOR T-800 1
TERMINATOR T-1000 2
TERMINATOR T-800 3
TERMINATOR T-800 4
在上面的第一行中,T-800是型号,1是序列号。上面的四行都是有效的,但如果第五行看起来像这样:
TORMONUTTUR T-800 1h6
或:
abc 2
,应丢弃数据,程序应继续读取下一行。
我目前在这方面感到迷茫,并希望只是朝着正确的方向点头,因为我不确定我应该如何解决这个问题。
答案 0 :(得分:1)
不要压倒自己的一种方法是将不同的行为委托给不同的功能,这样你就不必一次担心所有事情。我建议打开文件,一次读一行。对于每一行,您可以验证格式,然后将数据附加到链接列表,否则不执行任何操作并继续下一行。这可能看起来像这样。
char line[128];
while(fgets(line, 128, (FILE*)fh) != NULL) {
if(isValidLine(line)) {
// add data to linked list
}
}
逻辑很容易理解。您只需要定义函数isValidLine
来读取该行以确保其中包含有效数据,并返回相应的布尔值。要验证这一点,您可以使用sscanf
或其他字符串标记生成器来解析该行,或者手动执行此操作。例如,检查它是否以字符串"TERMINATOR "
开头并从那里继续。一切都检出,返回true,但在任何时候字符串都不符合您的格式要求,立即返回false。
答案 1 :(得分:0)
您可以阅读尝试以字符串形式读取该行的每个部分(例如,如果序列号为int
,则1h6将被截断,您将无法检查它是否有效)。对于序列号字符串,您应该检查它是否真的是整数,如果是,则转换为std::stoi
的数字。
从我的answer和How do I check if a C++ string is an int?,我得到了这个:
#include <fstream>
#include <iostream>
#include <string>
inline bool isInteger(const std::string & s)
{
if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false ;
char * p ;
strtol(s.c_str(), &p, 10) ;
return (*p == 0) ;
}
int main(void)
{
std::ifstream infile("thefile.txt");
if (infile.is_open()) {
int serial_number;
std::string model, terminator, serial_number_str;
while (infile >> terminator >> model >> serial_number_str)
{
if(terminator == "TERMINATOR" && isInteger(serial_number_str))
{
serial_number = std::stoi(serial_number_str);
std::cout << terminator << " " << model << " " << serial_number << "\n";
}
}
}
infile.close();
return 0;
}
对于文件:
Georgioss-MacBook-Pro:~gsamaras $ cat thefile.txt
TERMINATOR T-800 1
TERMINATOR T-1000 2
TERMINATOR T-800 3
TERMINATOR T-800 4
TORMONUTTUR T-800 1h6
abc 2
给出:
Georgioss-MacBook-Pro:~ gsamaras$ g++ main.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out
TERMINATOR T-800 1
TERMINATOR T-1000 2
TERMINATOR T-800 3
TERMINATOR T-800 4
您可以使用std::regex
检查model
的格式,进一步改进。