【问题标题】:Reading data from text file to linked list, error handling [closed]从文本文件读取数据到链表,错误处理[关闭]
【发布时间】:2017-11-09 11:42:21
【问题描述】:

我目前正在开发一个程序,该程序应该从文本文件中读取数据,并将所述数据放入链接列表中。我对自己在做什么有一个很好的了解,但问题是我应该包含错误处理,如果文件中的数据格式有任何错误,则跳转到下一行。

该文件以型号和序列号的形式包含有关许多终结器的信息。

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

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

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

我目前对此一头雾水,希望能朝正确的方向点头,因为我什至不知道应该如何着手解决这个问题。

【问题讨论】:

  • “我目前正在开发一个应该从文本文件中读取数据的程序”-> 发布您迄今为止所做的工作,以使这个原本广泛的问题更加清晰。

标签: c file validation linked-list


【解决方案1】:

一种不让自己不知所措的方法是将不同的操作委派给不同的功能,这样您就不必同时担心所有事情。我建议打开文件并一次读取一行。对于每一行,您可以验证格式,然后将数据附加到您的链表中,否则什么也不做,继续下一行。这可能看起来像这样。

char line[128];
while(fgets(line, 128, (FILE*)fh) != NULL) {
    if(isValidLine(line)) {
        // add data to linked list
    }
}

那里的逻辑很容易理解。您只需定义您的函数isValidLine 来读取该行以确保其中包含有效数据,并返回相应的布尔值。要验证这一点,您可以使用 sscanf 或其他字符串标记器来解析该行,或者自己手动执行。例如,检查它是否以字符串 "TERMINATOR " 开头并从那里继续。一切都检查出来,返回 true,但任何时候字符串不符合您的格式要求,立即返回 false。

【讨论】:

    【解决方案2】:

    您可以尝试将行的每一部分读取为字符串(因为如果序列号是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的格式来进一步改进它。

    【讨论】:

    • 您使用的是 C++,但答案被标记为 C。
    猜你喜欢
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多