2015-04-05 40 views
0

我已被學校分配創建一個應用程序,該應用程序包含一個包含20本不同書籍的書籍列表,並生成以下選項菜單:如何永久刪除一行數組並向上移動一行數組?

(a)列表 - 以列表格式顯示列表。每個展示應包含適當的標題和欄目標題; (b)搜索 - 使用ISBN在列表中搜索書籍記錄並打印該書籍的完整記錄;

(c)刪除 - 從列表中刪除現有書籍記錄;

(d)退出 - 停止程序。

這裏是我的方案的示例:

#include <iostream> 
#include <iomanip> 
#include <fstream> 
#include <cstring> 
#include <cctype> 

using namespace std; 

typedef struct 
{ 
    char code[50]; 
    char author[50]; 
    char name[50]; 
    char edition[50]; 
    char publish[50]; 
    char price[50]; 
} BOOK_LIST; 

void list   (BOOK_LIST book[], int rows); 
void showBook (BOOK_LIST book[], int rows); 
void updateRecord (BOOK_LIST book[], int rows); 
void advancedSearch (BOOK_LIST book[], int rows); 
int deleteBook (BOOK_LIST book[], int rows); 
int searchBook(BOOK_LIST book[], int rows); 

int main() 
{ 
    ifstream inFile("list.txt"); 

if(!inFile) 
    cout << "Error opening input file\n"; 
else 
{ 

    BOOK_LIST books[50]; 
    int index = -1, choice; 

    inFile.getline(books[++index].code, 50); 
    while(inFile) 
    { 
     if(inFile.peek() == '\n') 
      inFile.ignore(256, '\n'); 
     inFile.getline(books[index].author, 50); 
     inFile.getline(books[index].name, 50); 
     inFile.getline(books[index].edition, 50); 
     inFile.getline(books[index].publish, 50); 
     inFile >> books[index].price; 

     // read next number 
     inFile >> books[++index].code; 
    } 
    inFile.close(); 

    // menu starts 
    do 
    { 
     cout << "Do you want to:\n"; 
     cout << "1. List all books\n"; 
     cout << "2. Get details about a book\n"; 
     cout << "3. Delete a book from the list\n"; 
     cout << "4. Exit\n"; 
     cout << "5. Advanced Search\n"; 
     cout << "Enter choice: "; 
     cin >> choice; 

     switch (choice) 
     { 
      case 1 : list(books, index); 
        break; 
      case 2 : showBook(books, index); 
        break; 
      case 3 : updateRecord(books, index); 
        break; 
      case 5 : advancedSearch(books, index); 
      case 4 : break; 

      default: cout << "Invalid choice\n"; 
     } 
    } while (choice != 4); 

    ofstream outFile("list.txt"); 
    if(!outFile) 
     cout << "Error opening output file, records are not updated.\n"; 
    else 
    { 
     for (int i = 0; i < index; i++) 
     { 
      outFile << books[i].code << endl; 
      outFile << books[i].author << endl; 
      outFile << books[i].name << endl; 
      outFile << books[i].edition << endl; 
      outFile << books[i].publish << endl; 
      outFile << books[i].price << endl; 
     } 
     outFile.close(); 
    } 
} 
return 0; 
} 

void list(BOOK_LIST book[], int rows) 
{ 
    cout << fixed << setprecision(2); 
    cout << "ISBN\t  Author   BookName  Edition\tPublisher\t Price\n"; 
    for (int i = 0; i < rows; i++) 
     cout << book[i].code << "\t" << book[i].author << "\t" 
      << book[i].name << "\t" << book[i].edition << "\t" 
      << book[i].publish << "\t" 
      << " " << book[i].price << endl; 
    return; 
} 

int searchBook(BOOK_LIST book[], int rows) 
{ 
    int i = 0; 
    bool found = false; 
    char code[50]; 

cout << "Enter an ISBN code of a book to search: "; 
fflush(stdin); 
cin.getline(code, 50); 

while (i < rows && !found) 
{ 
    if (strcmp(code, book[i].code) == 0) 
     found = true; 
    else 
     i++; 
} 
if (found) 
    return i; 
else 
    return -1; 
} 

void showBook(BOOK_LIST book[], int rows) 
{ 
int pos = searchBook(book, rows); 
if (pos != -1) 
{ 
    cout << "Author is " << book[pos].author << endl; 
    cout << "Book name is "<< book[pos].name << endl; 
    cout << book[pos].edition << " Edition" << endl; 
    cout << "The publisher of this book is " << book[pos].publish << endl; 
    cout << "Current price is " << book[pos].price << endl; 
} 
else 
    cout << "Product not found\n"; 

return; 
} 

void updateRecord(BOOK_LIST book[], int rows) 
{ 
int pos = deleteBook(book, rows); 
char code [50]; 
int i,j = 0; 

    for(i = 0; i < rows ; i++) 
    { 
     if(strcmp(code, book[i].code)) 
     { 
      strcpy(book[j].code , book[i].code); 
      strcpy(book[j].author, book[i].author); 
      strcpy(book[j].name, book[i].name); 
      strcpy(book[j].edition, book[i].edition); 
      strcpy(book[j].publish, book[i].publish); 
      strcpy(book[j].price, book[i].price); 

      j++; 
     }//if 
     else 
     { 
      i++; 

     strcpy(book[j].code, book[i].code); 
     strcpy(book[j].author, book[i].author); 
     strcpy(book[j].name, book[i].name); 
     strcpy(book[j].edition, book[i].edition); 
     strcpy(book[j].publish, book[i].publish); 
     strcpy(book[j].price, book[i].price); 

     j++; 

    }//else 

}//for 
return; 
} 

int deleteBook (BOOK_LIST book[], int rows) 
{ 
int i = 0; 
bool found = false; 
char code[50]; 

cout << "Enter an ISBN code of a book to delete: "; 
fflush(stdin); 
cin.getline(code, 50); 

while (i < rows && !found) 
{ 
    if (strcmp(code, book[i].code) == 0) 
     found = true; 
    else 
     i++; 
} 
if (found) 
    return i; 
else 
    return -1; 
} 

void advancedSearch (BOOK_LIST book[], int rows) 
{ 

char advanced[50]; 
cout << "Please enter either the author's name or the book name to search: "; 
fflush(stdin); 
cin.getline(advanced, 50); 

for(int i = 0; i < rows; i++) 
{ 

    if(strstr(book[i].author, advanced) || strstr(book[i].name, advanced)) 
    { 
     cout << "ISBN is " << book[i].code << endl; 
     cout << "Author is " << book[i].author << endl; 
     cout << "Book name is " << book[i].name << endl; 
     cout << book[i].edition << " Edition" << endl; 
     cout << "Publisher is " << book[i].publish << endl; 
     cout << "Current price is " << book[i].price << endl; 
    } 

} 

return ; 
} 

這裏的問題開始: 當我想永久刪除本書記錄的整行。但刪除後該書記錄仍然存在。

首先,這是我的菜單,然後按1檢查IBSN的列表。然後,我按3進入刪除部分。那時候,我選擇TheHost刪除。在刪除後,以確保我已經刪除所選的書,所以我按1再次檢查之列,但不幸的是這本書仍然存在:

https://www.dropbox.com/s/planomxjuze9lul/Untitled2.png?dl=0

如果我能夠刪除一本書記錄,以及如何永久刪除記錄?刪除記錄後,如何向上移動剩餘的記錄,以便它不會留下空行?

爲刪除功能:

void updateRecord(BOOK_LIST book[], int rows) 
    { 
    int pos = deleteBook(book, rows); 
    char code [50]; 
int i,j = 0; 

    for(i = 0; i < rows ; i++) 
    { 
     if(strcmp(code, book[i].code)) 
     { 
      strcpy(book[j].code , book[i].code); 
      strcpy(book[j].author, book[i].author); 
      strcpy(book[j].name, book[i].name); 
      strcpy(book[j].edition, book[i].edition); 
      strcpy(book[j].publish, book[i].publish); 
      strcpy(book[j].price, book[i].price); 

      j++; 
     }//if 
     else 
     { 
      i++; 

     strcpy(book[j].code, book[i].code); 
     strcpy(book[j].author, book[i].author); 
     strcpy(book[j].name, book[i].name); 
     strcpy(book[j].edition, book[i].edition); 
     strcpy(book[j].publish, book[i].publish); 
     strcpy(book[j].price, book[i].price); 

     j++; 

    }//else 

}//for 
return; 
} 

The Text file that I used in this program a.k.a the BOOK_LIST

+0

請嘗試調試。 – 2015-04-05 13:57:12

+1

扔掉那些固定和動態大小的數組,並且替換'string'和'vector'是我會做的第一件事。但除此之外,我沒有看到你改變行數的點。你需要這樣做:擦除,複製每個元素後刪除pos下來1,然後縮小行數1.另外,將io/ui和業務邏輯代碼拆分成不同的功能。 – Yakk 2015-04-05 14:01:40

+0

你正試圖一次做幾件事。 **首先嚐試一些更簡單的方法**嘗試製作一個'int'數組,填充數字,然後刪除一個數字並移動其他數字以填補空白。一旦你有完美的工作,這將是容易的。一旦你解決了這個問題,你可以專注於學習1)[最小完整示例](http://stackoverflow.com/help/mcve),2)[basic_string](http://www.sgi.com/ tech/stl/basic_string.html)(比'char []'更容易處理),3)編寫一個Book類,並且集合* that *,而不是單獨收集書*所有東西。 – Beta 2015-04-05 14:02:12

回答

0

我發現(至少)你的代碼有兩個問題需要刪除一本書。

  1. update_record

    你使用的是被用來與strcmp以後比較,但沒有初始化的char code[50]

  2. 當您刪除圖書時,您應更新index,該圖書在update_record方法中變爲rows。但index按值傳遞給rows,這意味着即使您嘗試在update_record中運行--rows;,它也不會遞減index。您需要通過引用才能更新index


在一個側面說明,我同意就修理你的代碼中使用vectors/maps & strings,而不是簡單的數組和char*意見。
但既然你提到這是一個學校的任務,我猜你還沒有達到那種材料呢。

祝你好運。

+0

非常感謝你!是的,這是一項學校任務,這個項目全部通過或失敗。 – ProgrammingNoob 2015-04-05 15:21:17

0

分配最有可能希望你使用std::list模板,而不是傳統的數組c。插入和刪除對列表來說很自然。

另一種方法是使用std:map使用ISBN作爲關鍵字。國際標準書號應該是全球唯一的。

+0

我的老師剛纔教了我,直到如何輸入一個文本文件..我什麼都不知道進一步...順便說一句,感謝您的幫助:) – ProgrammingNoob 2015-04-05 15:10:39

0

爲了擴展我的評論,這裏是從數組中刪除元素的一種方法。

假設我們有的char陣列稱爲X,含有{ 'A', 'B', 'C', 'd', 'E', 'F'},我們希望擺脫'C'。如果我們想維護剩餘元素的順序,那麼我們的目標是{'a','b','d','e','f'}。因此,我們複製的「d」到「C」的地方,「E」到老「d」的地方,等:

a b c d e f 
a b d d e f 
a b d e e f 
a b d e f f 

我們可以用代碼來完成它像

for(int k=2; k<5; ++k) 
    X[k] = X[k+1]; 

最後那個額外的'f'會發生什麼?我們可以將一些佔位符寫入該不需要的空間,然後留意該佔位符進行剩餘的運行。或者,我們可以僅僅使用停止使用該空間,並且從現在開始我們正在考慮一個長度爲5的數組。這個額外的'f'仍然存在,但是現在我們不關心過去有什麼數組的末尾。

(如果我們如何處理餘下元素的順序不能護理,那麼我們就可以讓這個簡單了很多。)

請記住,它總是更容易開發孤立的新功能。

一旦你有這個工作,你可以在你的代碼中應用它,並獲得通過成績,但如果你真的想學一些有用的東西,你應該寫一個Book類。

+0

非常感謝您的指導,感謝您的幫助。 – ProgrammingNoob 2015-04-05 16:14:04