我正在创建一个应用程序来跟踪书店库存。它将文件路径带到包含信息的文本文件作为 main 的参数。我遇到的问题似乎是每当我尝试访问用于存储 Item 对象的类状态向量清单的元素时。首先是类标头,然后是方法定义,然后是 main。提前谢谢。
#ifndef _BOOKSTORE_H_
#define _BOOKSTORE_H_
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <stdlib.h>
#include "Item.h"
#include "Paperback.h"
#include "Hardcover.h"
#include "Audiobook.h"
#include "Ebook.h"
using namespace std;
class Bookstore {
//States
private:
vector<Item*> inventory;
//Behaviors
public:
Bookstore();
void loadInventory(const char*);
void searchInventory(string);
unsigned int inventorySize();
void printInventory();
vector<string> split(string);
};
#endif
#include "Bookstore.h"
Bookstore::Bookstore() {}
void Bookstore::loadInventory(const char* filepath) {
string ty = "";
string ti = "";
string au = "";
string pri = "";
string f = "";
string cd = "";
string pro = "";
string line;
ifstream ifs;
ifs.open (filepath);
if (ifs.is_open()) {
while (ifs.good()) {
ty = "";
ti = "";
au = "";
pri = "";
f = "";
cd = "";
pro = "";
getline(ifs, line);
if (line.compare("Paperback") == 0) {
ty = "Paperback";
getline(ifs, line);
ti = line;
getline(ifs, line);
au = line;
getline(ifs, line);
pri = line;
Paperback p(ty, ti, au, pri);
inventory.push_back(&p);
}
if (line.compare("Hardcover") == 0) {
ty = "Hardcover";
getline(ifs, line);
ti = line;
getline(ifs, line);
au = line;
getline(ifs, line);
pri = line;
getline(ifs, line);
f = line;
Hardcover h(ty, ti, au, pri, f);
inventory.push_back(&h);
}
if (line.compare("Audio") == 0) {
ty = "Audio";
getline(ifs, line);
ti = line;
getline(ifs, line);
au = line;
getline(ifs, line);
pri = line;
getline(ifs, line);
cd = line;
Audiobook a(ty, ti, au, pri, cd);
inventory.push_back(&a);
}
if (line.compare("Electronic") == 0) {
ty = "Electronic";
getline(ifs, line);
ti = line;
getline(ifs, line);
au = line;
getline(ifs, line);
pri = line;
getline(ifs, line);
pro = line;
Ebook e(ty, ti, au, pri, pro);
inventory.push_back(&e);
}
}
}
ifs.close();
cout << inventory.size() << endl;
for (unsigned int i=0; i<inventory.size(); i++) {
inventory.at(i)->printItem();
}
}
void Bookstore::searchInventory(string query) {
vector<string> searchStr;
int count;
string currentStr;
for (unsigned int i=0; i<inventory.size(); i++) {
currentStr = inventory.at(i)->getTitle();
searchStr = split(currentStr);
for(unsigned int j = 0; j < searchStr.size(); j++) {
if (searchStr[j].compare(query)==0) {
inventory.at(i)->printItem();
count++;
}
}
currentStr = inventory.at(i)->getAuthor();
searchStr = split(currentStr);
for(unsigned int j = 0; j < searchStr.size(); j++) {
if (searchStr[j].compare(query)==0) {
inventory.at(i)->printItem();
count++;
}
}
if ((i==(inventory.size()-1))&&(count==0)) {
cout << "Sorry, no matching results were found." << endl;
} else if ((i==(inventory.size()-1))&&(count!=0)) {
cout << "Query complete." << endl;
}
}
}
unsigned int Bookstore::inventorySize() {
unsigned int num = inventory.size();
return num;
}
void Bookstore::printInventory() {
for (unsigned int i = 0; i < inventory.size(); i++) {
inventory.at(i)->printItem();
}
}
vector<string> Bookstore::split(string s) {
vector<string> pieces;
istringstream iss(s);
copy(istream_iterator<string>(iss), istream_iterator<string>(),
back_inserter<vector<string> >(pieces));
return pieces;
}
#include "Bookstore.h"
int main(int argc, char** argv) {
Bookstore current;
if (argc==2) {
current.loadInventory(argv[1]);
}
cout << current.inventorySize() << endl;
//Initialize variables
char status = 'R';
string input = "";
int iter = 1;
//Run application until quit
while (status=='R') {
//Provide menu
if (iter==1) {
cout << "Welcome to Bookstore Inventory 9000." << endl;
}
if (current.inventorySize()==0) {
cout << "There are no entries!" << endl;
status = 'Q';
} else {
cout << "Would you like to (V)iew all, (S)earch, or (Q)uit?" << endl;
getline(cin, input);
if (input.compare("V")==0) {
current.printInventory();
} else if (input.compare("S")==0) {
cout << endl;
cout << "What are you looking for?" << endl;
getline(cin, input);
current.searchInventory(input);
cout << endl;
} else if (input.compare("Q")==0) {
status = 'Q';
cout << "Thank you for perusing our inventory. Goodbye." << endl;
} else {
cout << endl;
cout << "This is not a valid choice. Please try again." << endl;
cout << endl;
}
}
iter++;
}
return -1;
}
你的问题不在于at()
。 你的问题是你存储了一个局部变量的地址,然后你使用该指针,即使局部变量不再存在。
具体来说,在loadInventory
中,这里有一个例子:
if (line.compare("Paperback") == 0) {
ty = "Paperback";
getline(ifs, line);
ti = line;
getline(ifs, line);
au = line;
getline(ifs, line);
pri = line;
Paperback p(ty, ti, au, pri);
inventory.push_back(&p);
}
请注意倒数第二行如何创建名为"p"的局部(堆栈)变量。 在最后一行中,您获取该局部变量的地址并将其存储起来。 一旦代码命中上面引用中的最后一个大括号,名为"p"的变量就会消失,向量中的指针就不再有用了。
一种可能的解决方案是动态分配:
Paperback* p = new Paperback(ty, ti, au, pri);
inventory.push_back(p);
请注意,如果执行此操作,则必须在inventory
向量完成这些指针后自行删除这些指针。