2016-09-11 12 views
0

ユーザーがファイルに名前を付けてそのファイルを作成できるプログラムを作成しようとしています。私の問題は、その名前のファイルがまだ存在しないことを確認するためにエラーをチェックする必要があるときに来ました。私は、リンクされたリストにファイル名を置くことにしました。そして、新しいファイル名が前のファイル名と一致しないことを確認するために、リストが作成されるたびにリストを調べました。私のコードには他の関数がありますが、私はcreateDB関数がうまく動作するのを心配していますが、現在は名前がすでに使われていると言われていますし、デバッグをしてもcurr変数が常にNULLなのであるようです。どんな助けもありがとう。私が見リンクリストとファイルI/O C++

#include <iostream> 
#include <fstream> 
#include <stdio.h> 

using namespace std; 

class List{ 

private: 
    struct dataB{ //node 
     string name; 
     int open; //1 if open 0 if closed 
     dataB *next; 
    }; 
    // initializing node variables to go through linked list and search 
    dataB *head; 
    dataB *curr; 
    dataB *temp; 

public: 
    List(); 
    void insert(string name, int open); 
    bool search(string fName); 
    void createDB(); 
    void openDB(); 
    int menu(); 
}; //end class 

List::List(){ 
    head = NULL; 
    curr = NULL; 
    temp = NULL; 
} 
void List::insert(string name, int open){ 
    dataB *n = new dataB; 
    n->next = NULL; 
    n->name = name; 
    n->open = open; 

    if(head != NULL){ // if already things in list put it last 
     curr = head; 
     while(curr->next != NULL){ 
      curr = curr->next; 
     } 
     curr->next = n; // always puts new node at the end 
    } 
    else{ // if no list, make new node the start of list 
     head = n; 
    } 
} 

bool List::search(string fName){ //return false if no match, true if there is 
    curr = head; //start from beginning of list 
    bool match = true; 
    while(curr != NULL) { 
     if (fName != curr->name){ 
      curr = curr->next; 
      match = false; 
     } 
    } 
    return match; 
} 


void List::createDB() { 
    ofstream db; 
    string fileName; 
    List list; 
    cout << "Enter the name of the database you want to create: \n"; 
    getline (cin, fileName); 

    if(list.search(fileName) == false){ // means new filename, create db 
     db.open(fileName.c_str()); 
     cout << "\nYour database " << fileName << " was created successfully\n"; 
     list.insert(fileName, 0); 
    } 
    else if(list.search(fileName) == true) { // checking if the filename is taken 
     cout << "\nCould not create database because database name is already taken\n"; 
    } 
    else { 
     cout << "There was a problem creating the database"; 
    } 

    db.close(); 

} 

void List::openDB() { 
    // need to add check to see if one is already open 
    ofstream db; 
    string filename; 
    cout << "Enter the name of the database you want to open: "; 
    getline (cin, filename); 

    db.open(filename.c_str()); 

} 

void closeDB() { 
    cout << "The database _______ has been closed successfully"; 
} 

void display() { 
    cout << "Enter the ID of the employee you want to display: \n"; 
} 

void update() { 

} 

void report() { 

} 

void add() { 

} 

void del() { 

} 

int List::menu() { 
    cout << "Enter the number of the operation you wish to perform (1-9)\n" 
    << "1. Create new database\n" 
    << "2. Open database\n" 
    << "3. Close database\n" 
    << "4. Display record\n" 
    << "5. Update record\n" 
    << "6. Create report\n" 
    << "7. Add a record\n" 
    << "8. Delete a record\n" 
    << "9. Quit\n"; 

    int sel = 0; 
    (std::cin >> sel).ignore(); 

    switch (sel) { 
     case 1: createDB(); 
      menu(); // after creating file go back to list of options 
      break; 

     case 2: openDB(); 
      menu(); 
      break; 

     case 3: closeDB(); 
      menu(); 
      break; 

     case 4: display(); 
      break; 

     case 5: update(); 
      break; 

     case 6: report(); 
      break; 

     case 7: add(); 
      break; 

     case 8: del(); 
      break; 

     case 9: return 0; 
      break; 

     default: cout << "Please try again and enter a valid number\n\n"; 
      menu(); 
      break; 
    } 
    return true; // to avoid error saying control may reach end of non-void function 
} 


int main() { 
    List list; 
    list.menu(); 

    return 0; 
} 
+0

リンクリストの実装を練習する場合は、これで問題ありません。しかし、単に仕事をやりたいのであれば、ファイル名を 'std :: set 'に入れ、 'find()'があなたのためにすべての作業をするようにしてください。 –

+0

このような問題を解決する適切なツールは、デバッガです。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。最低限、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、その問題を再現するためのデバッガ。 –

答えて

1

問題:List::search()

問題1

実装が正しくありません。あなたは持っています:

bool List::search(string fName){ 
    curr = head; 

    // The initial value of match is true. 
    // When the list is empty, the function will return true. 
    // Not good. 
    bool match = true; 
    while(curr != NULL) { 
     if (fName != curr->name){ 
     curr = curr->next; 

     // It is set to false when there is no match 
     // But it is not reset to true when there is a match. 
     match = false; 
     } 
    } 
    return match; 
} 

実装はずっと簡単です。

bool List::search(string fName){ 
    curr = head; 
    while(curr != NULL) { 
     if (fName == curr->name){ 

     // If a match is found, return true 
     // There is no need to continue any more checks. 
     return true; 
     } 
    } 

    // If we come here, there is no match. 
    // Return false. 
    return false; 
} 

問題2

あなたは新しいListにファイルをあなたがcreateDB()を呼び出すたびに検索しています。

あなたが持っている:

List list 

が新しいListあなたがList::createDB()を呼び出すたびに作成されます

void List::createDB() { 
    ofstream db; 
    string fileName; 
    List list; 
    ... 
} 

ライン。したがって、その関数内のlistオブジェクトの呼び出しは、常に関数ローカルオブジェクト上にあり、createDB()が呼び出されたオブジェクトではありません。

listの代わりにthisを使用する必要があります。

void List::createDB() { 
    ofstream db; 
    string fileName; 

    // Don't need this. 
    // List list; 
    cout << "Enter the name of the database you want to create: \n"; 
    getline (cin, fileName); 

    // Use this instead of list 
    // if(list.search(fileName) == false){ // means new filename, create db 
    if(this->search(fileName) == false){ // means new filename, create db 
     db.open(fileName.c_str()); 
     cout << "\nYour database " << fileName << " was created successfully\n"; 

     // Use this instead of list 
     // list.insert(fileName, 0); 
     this->insert(fileName, 0); 
    } 

    // You don't really need this->search() again. That function 
    // has already returned false. 
    // else if(list.search(fileName) == true) { // checking if the filename is taken 
    else{ 
     cout << "\nCould not create database because database name is already taken\n"; 
    } 

    // This block is not needed any more. 
    // else { 
    //  cout << "There was a problem creating the database"; 
    // } 

    db.close(); 
} 
関連する問題