将数据从文本文件读取到链表,错误处理

时间:2017-06-07 23:12:30

标签: c file validation linked-list

我目前正在研究一个应该从文本文件中读取数据的程序,并将所述数据放在链表中。我对我正在做的事情有了很好的了解,但问题是,如果数据格式中存在任何错误,我应该包含错误处理,跳转到下一行。文件。

该文件包含有关模型形式及其序列号的多个终结器的信息。

可以读取的数据示例如下:

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

,应丢弃数据,程序应继续读取下一行。

我目前在这方面感到迷茫,并希望只是朝着正确的方向点头,因为我不确定我应该如何解决这个问题。

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的数字。

从我的answerHow 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的格式,进一步改进。