3

C ++のファイルからIDで特定の行を削除しようとしていますが、これが私のコードです:

void deleteRow()
{
    ifstream inDb("files/students.dat", ios::in);
    if(!inDb)
    {
        cerr << "File could no be opened!\n";
    }

    cout << countRowsOfDb() << " records." << endl;

    Student *studentsArray[countRowsOfDb()];

    int n = 0;

    while(inDb >> id >> name >> grade >> points >> type)
    {
        studentsArray[n] = new Student(id, name, grade, points, type);
        n++;
    }

    inDb.close();

    for(int i = 0; i < countRowsOfDb(); i++)
    {
        cout << studentsArray[i]->id << " " << studentsArray[i]->name << " " << studentsArray[i]->grade << " "
             << studentsArray[i]->points << " " << studentsArray[i]->type << "\n";
    }

    cout << "\nWhich one you would like to delete? Enter an id: ";

    string term;
    cin >> term;

    ofstream outDb("files/students.dat", ios::out);
    if(!outDb)
    {
        cerr << "File could no be opened!\n";
    }


    for(int i = 0; i < countRowsOfDb(); i++)
    {
        if(studentsArray[i]->id != term)
        {
                outDb << studentsArray[i]->id << " " << studentsArray[i]->name << " " << studentsArray[i]->grade << " "
                      << studentsArray[i]->points << " " << studentsArray[i]->type << "\n";
        }
    }

    outDb.close();

    cout << "\nObject deleted!\n";
}

入力ファイルストリームを作成し、すべての行を取得し、オブジェクトの配列にして画面に表示し、IDを入力して削除するものを尋ねます。IDを入力すると、これらすべてを配置しようとしています配列の要素は同じIDの要素なしでのみですが、機能しません。その後、ファイルには何もありません。何か案は?

4

2 に答える 2

2

何が入っていcountRowsOfDb()ますか?ファイルを開いてその中の行を数える場合(そして他に何ができるかわかりません)、同じ名前のostreamを作成すると、最後のループで多くが見つかることはありません。ファイルを空にしました。

より一般的には、これは非常に非効率的な方法です(ファイルの形式にエラーがあった場合、簡単に失敗する可能性があります)。これを処理する最良の方法は、を使用することstd::vector<Student>です。

studentVector.push_back( Student( id, name, grade, points, type ) );

入力ループで。後のすべてのループで、studentVector.size()エントリの数を指定するか、イテレータを使用できます。

さらに良いのはstd::getline、入力で使用してから、を初期化しstd::istringstreamて各行を解析することです。これにより、入力フォーマットエラーをより確実にキャッチできます。何かのようなもの:

std::string line;
int lineNumber = 0;
while ( std::getline( inDb, line ) ) {
    ++ lineNumber;
    std::istringstream data( line );
    if ( data >> id >> name >> grade >> points >> type ) {
        studentVector.push_back( Student( id, name, grade, points, type ) );
    } else {
        std::cerr << "Format error in lne " << lineNumber << std::endl;
    }
}

また、一般的には、別のファイルに書き込み、書き込みが機能したことを確認した後で名前を変更することをお勧めします。

std::ofstream outDb( "files/students.dat.new" );
//  Do output...
outDb.close();
if ( outDb ) {
    remove( "files/students.dat" );
    rename( "files/students.dat.new", "files/students.dat" );
} else {
    std::cerr << "Write error on output" << std::endl;
}

EXIT_FAILUREそしてもちろん、書き込みエラーが発生すると、 fromが返さ れmainます。(これは、グローバル変数またはシングルトンが正当化される1つのケースであり、戻りコードを追跡します。)

于 2012-06-13T13:00:21.377 に答える
0

コンテンツを再生する新しい関数を追加して機能するようにしたので、コードは次のようになります。

void deleteRow()
{
    ifstream inDb("files/students.dat", ios::in);
    if(!inDb)
    {
        cerr << "File could no be opened!\n";
    }

    cout << countRowsOfDb() << " records." << endl;

    Student *studentsArray[countRowsOfDb()];

    int n = 0;

    while(inDb >> id >> name >> grade >> points >> type)
    {
        studentsArray[n] = new Student(id, name, grade, points, type);
        n++;
    }

    inDb.close();

    for(int i = 0; i < countRowsOfDb(); i++)
    {
        cout << studentsArray[i]->id << " " << studentsArray[i]->name << " " << studentsArray[i]->grade << " "
             << studentsArray[i]->points << " " << studentsArray[i]->type << "\n";
    }

    cout << "\nWhich one you would like to delete? Enter an id: ";

    string term;
    cin >> term;

    for(int i = 0; i < countRowsOfDb(); i++)
    {
        if(studentsArray[i]->id != term)
        {
            Student studentTemp(studentsArray[i]->id, studentsArray[i]->name, studentsArray[i]->grade, studentsArray[i]->points, studentsArray[i]->type);
            replaceRow(studentTemp);
        }
    }

    cout << "\nObject deleted!\n";
}

置換機能は次のとおりです。

void replaceRow(Student student)
{
    ofstream outDb("files/students.dat", ios::out);
    if(!outDb)
    {
        cerr << "File could no be opened!\n";
    }

    outDb << student.getId() << ' ' << student.getName() << ' ' << student.getGrade()
          << ' ' << student.getPoints() << ' ' << student.getType() << endl;

    outDb.close();
}
于 2012-06-13T12:58:28.027 に答える