【问题标题】:Debug Error Thrown When Checking !str.find()检查 !str.find() 时抛出调试错误
【发布时间】:2021-09-01 23:49:09
【问题描述】:

我正在学习 C++。我正在开发一个简单的“图书馆管理”应用程序,它允许用户创建帐户、签出书籍等。每本书都使用唯一的文本文件进行管理。文本文件包含如下三行,但是第三行是这里唯一重要的内容,因为它包含了书的所有者。

以下代码打印了一个包含所有书籍列表的附加文本文件的内容,但这与错误无关。它将文本文件的内容转换为字符串,然后检查是否存在“NA”。如果存在“NA”,则将其替换为当前用户名。然后使用ios::trunc 重新打开文件以擦除文件,并将新字符串传递到文件中。这很好用。

问题是在运行应用程序时,如果用户名已经存在而不是“NA”,我会得到一个Debug Error,它只读取abort() has been called。我已尝试调试,但无法获得更多信息。

这是错误和代码:

void bookCheckout()
{
    system("CLS");
    string line;
    string bookChoice;
    ifstream checkBookList;
    ofstream checkOutBook;
    checkBookList.open("books/booklist.txt");
    
    string sTotal;
    string s;

    

    cout << "<---Avaliable Books--->" << endl;
    while (getline(checkBookList, line)) {
        cout << line << endl;
    }
    checkBookList.close();

    cout << "\nWhat Book Would You Like?:";
    cin >> bookChoice;

    checkBookList.open("books/" + bookChoice + ".txt");
    while (!checkBookList.eof()) {
        getline(checkBookList, s);
        sTotal += s + "\n";
    }

    checkBookList.close();
    if (sTotal.find("NA")) {
        sTotal.replace(sTotal.find("NA"), 2,  globalUsername);
        checkOutBook.open("books/" + bookChoice + ".txt", ios::trunc);
        checkOutBook << sTotal;
        checkOutBook.close();
    }
    else if (!sTotal.find("NA")) {
        
        cout << "Book already checked out!" << endl;
    }
    
    checkOutBook.close();
    


    
    system("PAUSE");

    

}

【问题讨论】:

  • 你的错误对话框有Retry按钮;你点击了吗?
  • 我按下了重试按钮,然后我得到一个框,上面写着“Library Management System.exe 已停止工作”
  • 如果您构建 Debug 配置并运行“调试”(F5),那么重试应该会将您带到失败的地方。
  • while (!checkBookList.eof()) { - 见Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong? if (sTotal.find("NA")) { - string::find() 返回一个索引,而不是布尔值。如果您的目标是找到一条写有"NA" 的LINE,那么使用find() 并不是实现此目的的最佳选择。 else if (!sTotal.find("NA")) { - 根本不需要在else 中调用find()
  • 我添加了正确的代码并且它可以工作。非常感谢。我是 C++ 新手,我敢肯定你能看出来。

标签: c++ visual-studio file-handling


【解决方案1】:

您的代码存在一些问题:

此外,您的目标是检查 3RD LINE 是否明确"NA",因此使用 string::find() 不是该目的的最佳选择。想想如果第一行或第二行恰好包含字母NA会发生什么。您的代码逻辑将无法正常运行。

  • else if (!sTotal.find("NA")) - 根本不需要在else 中调用find()。只需单独使用else

话虽如此,请尝试更多类似的东西:

void bookCheckout()
{
    system("CLS");

    ifstream checkBookList;

    checkBookList.open("books/booklist.txt");
    if (!checkBookList.is_open()) {
        cerr << "Unable to open booklist.txt" << endl;
        return;
    }

    string line;

    cout << "<---Available Books--->" << endl;
    while (getline(checkBookList, line)) {
        cout << line << endl;
    }
    checkBookList.close();

    cout << "\nWhat Book Would You Like?:";

    string bookChoice;
    getline(cin, bookChoice);

    checkBookList.open("books/" + bookChoice + ".txt");
    if (!checkBookList.is_open()) {
        cerr << "Unable to open " + bookChoice + ".txt for reading" << endl;
        return;
    }

    string sTotal, sOwner;
    int lineNum = 0;
    string::size_type ownerIndex = string::npos;

    while (getline(checkBookList, line)) {
        ++lineNum;
        if (lineNum == 3) {
            sOwner = line;
            ownerIndex = sTotal.size();
        }
        sTotal += line + "\n";
    }

    checkBookList.close();

    if (sOwner == "NA") {
        sTotal.replace(ownerIndex, 2, globalUsername);

        ofstream checkOutBook("books/" + bookChoice + ".txt", ios::trunc);
        if (!checkOutBook.is_open()) {
            cerr << "Unable to open " + bookChoice + ".txt for writing" << endl;
            return;
        }

        checkOutBook << sTotal;
        checkOutBook.close();

        cout << "Book checked out!" << endl;
    }
    else {
        cout << "Book already checked out by " << sOwner << "!" << endl;
    }

    system("PAUSE");
}

或者,使用std::vector 来收集图书内容,这样您就可以对每一行进行索引访问:

#include <vector>

void bookCheckout()
{
    system("CLS");

    ifstream checkBookList;

    checkBookList.open("books/booklist.txt");
    if (!checkBookList.is_open()) {
        cerr << "Unable to open booklist.txt" << endl;
        return;
    }

    string line;

    cout << "<---Available Books--->" << endl;
    while (getline(checkBookList, line)) {
        cout << line << endl;
    }
    checkBookList.close();

    cout << "\nWhat Book Would You Like?:";

    string bookChoice;
    getline(cin, bookChoice);

    checkBookList.open("books/" + bookChoice + ".txt");
    if (!checkBookList.is_open()) {
        cerr << "Unable to open " + bookChoice + ".txt for reading" << endl;
        return;
    }

    vector<string> sTotal;
    sTotal.reserve(3);

    while (getline(checkBookList, line)) {
        sTotal.push_back(line);
    }

    while (sTotal.size() < 3) {
        sTotal.push_back("");
    }

    checkBookList.close();

    if (sTotal[2] == "" || sTotal[2] == "NA") {
        sTotal[2] = globalUsername;

        ofstream checkOutBook("books/" + bookChoice + ".txt", ios::trunc);
        if (!checkOutBook.is_open()) {
            cerr << "Unable to open " + bookChoice + ".txt for writing" << endl;
            return;
        }

        for(size_t i = 0; i < sTotal.size(); ++i) {
            checkOutBook << sTotal[i] << '\n';
        }
        checkOutBook.close();

        cout << "Book checked out!" << endl;
    }
    else {
        cout << "Book already checked out by " << sTotal[2] << "!" << endl;
    }

    system("PAUSE");
}

【讨论】:

  • 非常感谢。我将重新编码几次以真正将其牢牢地印在我的脑海中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
相关资源
最近更新 更多