解析书籍数据文件

Parsing a file of book data

提问人:Bill Brown 提问时间:9/1/2023 最后编辑:Bill Brown 更新时间:9/1/2023 访问量:52

问:

我正在尝试解析包含书籍信息的文件。该文件的结构如下。“饥饿游戏,978-1-40-710908-4,0”。这一切都在一行上,然后重复。书名《饥饿游戏》需要进入一个载体。ISBN 编号“978-1-40-710908-4”进入另一个向量,最后最后一个个位数数字将进入另一个向量。

但是,该文件可能缺少一些东西,例如,一行可能看起来像这样,“哈利波特,978-1-40-528790-9”。如您所见,缺少最后一个数字,如果它不存在于行中,则应默认为“0”。另一行可能看起来像这个“Book”,它没有 ISBN 或最后一个数字。每当什么都没有时,我都无法输入信息,就像上面的两个例子一样。这是我到目前为止的简单代码。我只被允许使用下面的库,所以没有 sstream。

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <cctype>
using namespace std;

int main()
{
    vector <string> BookName;
    vector <string> BookNum;
    vector <string> BookAvailability;
    ifstream inFS;

    inFS.open("file_name.txt");
    string line;
    while (!inFS.fail()) {
        getline(inFS, line);
        int firstComma = line.find(',');
        int secondComma = line.find(',', firstComma + 1);

        string bookName = line.substr(0, firstComma);

        string bookISBN = "000-0-00-000000-0";
        string bookAvail = "0";

        if (firstComma != string::npos) {

            if (secondComma != string::npos) {
                bookISBN = line.substr(firstComma + 2, secondComma - firstComma - 2);
            }
            if (secondComma != string::npos || line.find('-', firstComma + 1) == string::npos) {
                bookAvail = line.substr(secondComma + 2);
            }

            BookName.push_back(bookName);
            BookNum.push_back(bookISBN);
            BookAvailability.push_back(bookAvail);

        }
    }

    // This for loop is only for testing 
    for (int i = 0; i < BookName.size(); i++) {
        cout << "Name : " << BookName.at(i) << endl;
        cout << "ISBN : " << BookNum.at(i) << endl;
        cout << "Digit : " << BookAvailability.at(i) << endl;
    }
    return 0;
}

下面是文件外观的示例。

Harry Potter, 978-1-40-710908-4, 0
Red Rising, 978-0-55-339079-7, 0
Where the Wild Things Are, 978-1-43-520892-6, 2
Spider Man, 978-0-06-020706-9, 1
Good Will Hunting, 978-3-89-687070-4
Star Wars: Ahsoka, 978-1-40-528790-9 
Book
Master & Apprentice, 978-0-52-561937-7, 1
The C Programming Language, 978-0-87-692596-6, 7
Oops, 978-12-40-528790-9
Snow Crash, 978-3-44-223686-2, 3

我想知道如何修复我的代码?

Name : The Hunger Games
ISBN : 978-1-40-710908-4
Digit : 0
Name : Red Rising
ISBN : 978-0-55-339079-7
Digit : 0
Name : Where the Wild Things Are
ISBN : 978-1-43-520892-6
Digit : 2
Name : Goodnight Moon
ISBN : 978-0-06-020706-9
Digit : 1
Name : The Ultimate Hitchhiker's Guide
ISBN : 000-0-00-000000-0
Digit : 0
Name : Star Wars: Ahsoka
ISBN : 000-0-00-000000-0
Digit : 0
Name : Master & Apprentice
ISBN : 978-0-52-561937-7
Digit : 1
Name : The C Programming Language
ISBN : 978-0-87-692596-6
Digit : 7
Name : Oops
ISBN : 000-0-00-000000-0
Digit : 0
Name : Snow Crash
ISBN : 978-3-44-223686-2
Digit : 3
Name : Snow Crash
ISBN : 978-3-44-223686-2
Digit : 3

我尝试更改会更改 ISBN 和图书可用性编号的 if 语句,但没有任何效果?

以下是当前的输出。我怎样才能改变我的代码,使这些值与文件上的值相对应。

我希望我的代码会读取所有行。将书名放入 BookName 向量中,将图书 ISBN 放入 bookISBN 编号中,将图书可用性放入 BookAvailability 向量中。如何更改代码以执行此操作?

C++ 文件 解析

评论

1赞 Lærne 9/1/2023
那么,有什么问题?它会崩溃吗?在哪里(使用调试器知道在哪里)?
1赞 user4581301 9/1/2023
注意:在程序执行任何 IO 之前测试故障,并且不检测失败。改用读取,测试读取是否成功,如果测试通过,则进入循环。while (!inFS.fail())getline(inFS, line);while (getline(inFS, line))
1赞 Ted Lyngmo 9/1/2023
标题中带有逗号的书籍是否被禁止进入该图书馆?
2赞 user4581301 9/1/2023
建议:不要有三个单独的 s,并且必须使它们保持同步,而是创建一个结构,将三个 s 中的数据聚合起来,并具有该结构中的单个。将所有每行数据保存在一个地方通常会使搜索和排序更容易编写,而搜索和排序肯定会很快达到几个数量级。vectorvectorvector
1赞 PaulMcKenzie 9/1/2023
你真的应该创建一个函数来解析一行,并返回信息。现在你已经把所有东西都塞进去了,使代码更难维护和测试。我期望一个函数,也许@user4581301提到的那个结构在哪里,这就是你从文件中得到的行(你甚至不需要一个文件 - 只需使用硬编码的字符串数据调用函数)。这样可以很容易地测试该功能,并且文件处理只是整个问题的次要问题。mainYourStruct ParseData(std::string line){ }YourStructline

答:

0赞 Bill Brown 9/1/2023 #1

取出 3 个 push_back() 声明并将它们放在 if 语句之外。 同时更改 2 if 语句

if (firstComma != string::npos) {
            bookNum = line.substr(firstComma + 2, secondComma - firstComma - 2);
            bookAvail = line.substr(secondComma + 2);
        }
        if (secondComma == string::npos) {
            bookAvail = "0";
        }

评论

0赞 user4581301 9/1/2023
SO 使用说明:要获得强有力的答案,您需要解释出了什么问题以及建议的更改如何解决问题。这使得未来找到此页面的提问者更容易学习答案。
0赞 tbxfreeware 9/2/2023
感谢您分享修复程序。你给了自己一个答案!对于后来的读者来说,有更多的解释可能会有用。例如,您可以说出为什么调用需要在 if 语句之外。如果他们不在外面会怎样?此外,您可能希望显示与问题中的代码相同的代码,而不仅仅是一个片段。您是否从评论中采纳了任何其他建议,例如,关于进入声明的建议?push_backgetlinewhile