检查 !str.find() 时抛出调试错误
Debug Error Thrown When Checking !str.find()
我正在学习 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");
}
您的代码存在一些问题:
缺乏错误处理。
while (!checkBookList.eof())
- 参见 Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())
) considered wrong?
if (sTotal.find("NA"))
- string::find()
returns 一个索引,而不是布尔值。如果返回 0,则将被评估为 false。所有其他值都将被评估为 true,包括 string::npos
(-1),如果未找到匹配项,这就是 string::find()
returns。
此外,您的目标是检查 3RD LINE SPECIFICALLY 是否为 "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");
}
我正在学习 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");
}
您的代码存在一些问题:
缺乏错误处理。
while (!checkBookList.eof())
- 参见 Why is iostream::eof inside a loop condition (i.e.while (!stream.eof())
) considered wrong?if (sTotal.find("NA"))
-string::find()
returns 一个索引,而不是布尔值。如果返回 0,则将被评估为 false。所有其他值都将被评估为 true,包括string::npos
(-1),如果未找到匹配项,这就是string::find()
returns。
此外,您的目标是检查 3RD LINE SPECIFICALLY 是否为 "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");
}