从文件中删除特定行 [英] Delete specific line from file

查看:76
本文介绍了从文件中删除特定行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从C ++中的文件中按ID删除特定行,这是我的代码:

I'm trying to delete a specific line by id from a file in C++ and here is my code:

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的元素中,但是在文件中没有任何内容之后,它不起作用.有什么想法吗?

I create a input file stream and then get all the rows, make it array of objects and show them on the screen then ask which one to delete by typing an id, and when I type the id, I'm trying to put all these elements of the array only without the element with same id, but it don't works, after that there is nothing in the file. Any ideas?

推荐答案

countRowsOfDb()中包含什么?如果打开文件并计算行数在其中(我不知道它还能做什么),那么它就不会在最后的循环中找到了很多,因为使用相同名称的文件将被清空.

What's in countRowsOfDb()? If it opens the file and counts the lines in it (and I don't know what else it could do), then it's not going to find a lot in the final loop, since the creation of the ostream with the same name will have emptied the file.

更一般而言,这是一种非常低效的处理方式(并且如果文件格式有错误,则很容易失败).处理此问题的最佳方法是使用 std :: vector< Student> ,并带有:

More generally, this is a very inefficient way of doing things (and could easily fail if there were an error in the format of the file). The best way to handle this is to use an std::vector<Student>, with:

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

输入循环中的

.在以后的所有循环中, studentVector.size()给出了数量的条目,或者您可以使用迭代器.

in the input loop. In all later loops, studentVector.size() gives the number of entries, or you can use the iterators.

更好的方法是在输入,然后初始化一个 std :: istringstream 来解析每一行.这将更可靠地捕获输入格式错误.像这样:

Even better would be to use std::getline on the input, then initialize an std::istringstream to parse each line. This will catch input format errors much more reliably. Something like:

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

此外,通常最好将其写入单独的文件,然后在确认写入有效后 将其重命名,即:

Also, it is generally a better idea to write to separate file, then rename it after having verified that the write worked, i.e.:

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

当然,任何写入错误都应导致返回来自 main EXIT_FAILURE .(在这种情况下,全局变量或单例是合理的-跟踪返回码.)

And of course, any write error should result in a return of EXIT_FAILURE from main. (This is one case where a global variable or a singleton is justified—keeping track of the return code.)

这篇关于从文件中删除特定行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆