链表和文件I / O C ++

时间:2016-09-11 03:38:45

标签: c++ linked-list

我正在尝试创建一个允许用户命名文件的程序,然后创建该文件。当我需要进行错误检查以确保没有具有该名称的文件时,我的问题就来了。我决定将文件名放入链接列表中,然后每次创建一个链接列表后,它将遍历列表以确保新文件名与之前的文件名不匹配。我的代码中还有其他函数,但我只担心让createDB函数正常工作,现在它只是总是说已经采用了名称,并且做了一些调试似乎是因为我的curr变量总是为NULL。任何帮助将不胜感激。

#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;
}

1 个答案:

答案 0 :(得分:1)

我看到的问题:

问题1

List::search()的实施不正确。你有:

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()内搜索该文件。

你有:

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

该行

   List list
每次拨打List时,

都会创建一个新的List::createDB()。因此,对该函数中list对象的调用始终位于函数本地对象上,而不是调用createDB()的对象。

您需要在该功能中使用this代替list

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();
}