-1

ファイルからデータベースを読み込もうとしています。

私の save_base メソッドは次のとおりです。

void data_base::save_base()
{
    fstream file;

    file.open("base.dat", ios::in | ios::out | ios::trunc);

    if(file.good()==true) {
        node *p = new node();
        p=first;

        while(p) {
            file << p->content->connect() << ";" << "\n";
            p=p->next;
        }
        file.close();
    }else{
    cout << "Err - opening file." << endl;
    }
}

接続方法:

string product::connect() {

    ostringstream do_string;
    do_string << lp;
    string new_lp = do_string.str();

    ostringstream do_string1;
    do_string1 << count;
    string new_count = do_string1.str();

    ostringstream do_string2;
    do_string2 << prize;
    string new_prize = do_string2.str();

    ostringstream do_string3;
    do_string3 << vat;
    string new_vat = do_string3.str();

    string connected = type + ";" + new_lp + ";" + name + ";" + new_count + ";" + unit + ";" + new_prize + ";" + new_vat;
    return connected;
}

および read_base メソッド:

void data_base::read_base()
{
    fstream file;

    file.open("base.dat", ios::in);
    if(file.good()==true)
    {
        char data_row[50];
        int i=1;
        while(!file.eof()) {
            file.getline(data_row,100);

        string data_content[50];
        int j = 0;

        char *buff;
        buff = strtok (data_row,";");
        while (buff != NULL)    {
            data_content[j] = buff;
            buff = strtok (NULL, ";");
            j++;
        }
        string type = data_content[0];
        int lp;
        istringstream iss1(data_content[1]);
        iss1 >> lp;
        double count;
        istringstream iss2(data_content[3]);
        iss2 >> count;
        double prize;
        istringstream iss3(data_content[5]);
        iss3 >> prize;
        double vat;
        istringstream iss4(data_content[5]);
        iss4 >> vat;

        // Sprawdzamy typ obiektu zapisanego w danym wierszu pliku
        if(type == "product")
        {

            product new_prod(lp, data_content[2], count, data_content[4], prize, vat);
            product *new_product = new product(new_prod);
            this->add(new_product);
        }
        i++;
        }
    file.close();
    }else{
        cout << "Err opening file." << endl;
    }
}

データベースにいくつかの製品を追加していますが、正常に動作します。ファイルへの保存でもうまくいきます。しかし、主な問題は、ファイルからデータベースを読み取ろうとするときです。ファイルからのデータベースの読み取りは正常に機能しますが、最後に、アプリケーションはそれ自体では終了しません。閉じるバッファがまだいくつかあると思います。しかし、どれがどれだけ近いかはわかりません。

4

2 に答える 2

1

正直なところ、このコードでは非常に多くの問題が発生しています。主な問題は、おそらくまだカプセル化に取り組んでいることにあると思います。あなたのコードは C と C++ のスタイルを組み合わせて使用​​しているため、コードが読みづらく、保守が困難になることが保証されています。

そうは言っても、問題は保存時に「new node()」を呼び出しているように見えますが、これは保存しているように見えます...何もありません。製品内の既存の値を照会するべきではありませんか? 編集:ああ、いいえ、「p = first」に再割り当てしますね。なるほど。では、前の行で割り当てたノードはどうなるでしょうか?

行のいずれかが 50 バイトを超えると、潜在的なスタック クロバーも発生します。

char data_row[50];
int i=1;
while(!file.eof()) {
    file.getline(data_row,100);

char 配列を使用する必要がある場合は、sizeof を使用する習慣を身につけてください。

file.getline(data_row, sizeof(data_row));

istringstream の目的を理解するのに少し時間がかかりました。文字列を数値に変換しようとしていますか? 次のように書くと、よりシンプルで効率的になります。

unsigned int lp = atoi(data_content[1].c_str());
or
unsigned int lp = strtoul(data_content[1].c_str(), NULL, 10);

データベースの一部である read_base 関数は、データ レコードについて WAAAAY を認識しすぎています。read_base が次のようになるように、レコードの母集団をカプセル化する必要があります。

void data_base::read_base()
{
    fstream file("base.dat", ios::in);
    if(file.good() == false) {
        cout << "Error opening file." << endl;
        return;
    }

    for(size_t rowNo = 0; !file.eof(); ++rowNo) {
        row* row = data_type::make_object_from_row(file);
        if(row != nullptr)
            this->add(row);
        }
    }
}

これを可能にする data_row 基本型を実装する方法については、「Factory パターン」を調べる必要がある場合があります。しかし、要するに、製品に data_type を継承させて、上記が機能するようにします。data_type::make_object_from_row は、行の最初の部分を読み取り、型を列挙して、次のようなことができるようにします。

data_type* data_type::make_object_row_row(istream& file) {
    switch(get_type(file)) {
        case DATA_TYPE_PRODUCT: return new product(file);
        case DATA_TYPE_PERSON: return new person(file);
        default:
          clog << "invalid type in database: " << type << endl;
          return nullptr;
    }
}

(これは可能なアプローチの 1 つにすぎません)。

于 2013-05-20T00:19:49.153 に答える