删除并替换 .txt 文件中的特定行

Delete and replace a Specific Line in .txt file

我正在努力处理与文件处理相关的 C++ 项目,需要帮助。

这是我的 movies.txt 文件

SNO, Name, NoOfPeopleLiked
1, The Shawshank Redemption, 77 
2, The Godfather, 20        
3, Into The Wild, 35
4, The Dark Knight, 55      
5, 12 Angry Men, 44     
6, Schindler's List, 33
7, The Lord of the Rings: The Return of the King, 25
8, Pulp Fiction, 23
9, The Good, the Bad and the Ugly, 32   
10, The Lord of the Rings: The Fellowship of the Ring, 56

我想通过输入该行的电影名称来删除特定行。对于示例,当我输入电影名称“12 Angry Men”时,应删除整行第 5 行并替换为增加了 [= 的更新行27=]NoOfPeopleLiked 值从 5, 12 Angry Men, 445, 12 Angry Men, 45。 每当我输入电影名称时,如何删除该特定行并更新喜欢的值?


但是当我输入电影名称时,所有行都被删除,直到第 6 行,输出 文件看起来像这样。


    , Schindler's List, 33
7, The Lord of the Rings: The Return of the King, 25
8, Pulp Fiction, 23
9, The Good, the Bad and the Ugly, 32   
10, The Lord of the Rings: The Fellowship of the Ring, 56

请帮我解决这个问题? 这是我的代码:

void search()
{
    ifstream file;
    file.open("movies.txt");
    cout << "Enter the name of Movie : " << ' ';
    getline(cin, search_movie);
    if (file.is_open())
    {
        while (getline(file, line, ','))
        {
            if ((line.find(search_movie, 0)) != string::npos)
            {
                file >> liked;
                file >> serial;
                cout << serial << " The movie '" << search_movie << "' has been found in database and " << liked << " people like this movie" << endl;
                cout << "Do you like it as well (y/n)" << ' ';
                char z;
                cin >> z;
                if (z == 'y' || z == 'Y')
                {
                    update(search_movie, file);
                }
            }
        }
    }
    else
    {
        cout << "your file could not be opened" << endl;
    }
    file.close();
}

    void update(string search_movie, ifstream& file1)
    {
        ofstream temp;
        string linee;
        temp.open("temp.txt", ios::out);
        while (getline(file1, linee))
        {
            cout << linee << endl;
            if (line.substr(0, search_movie.size()) != search_movie)
            {
                temp << linee << endl;
            }
        }
        file1.close();
        temp.close();
        remove("movies.txt");
        rename("temp.txt", "movies.txt");
    }
};

这是您想要执行的操作的工作示例:增加电影的点赞数。它不会将整个文件的内容存储到缓冲区中。该文件可能很大,因此效率可能不高。

#include <fstream>
#include <iostream>
#include <string>
 
int main()
{
    std::fstream fileMovies{"sample.txt",
                            std::ios_base::in | std::ios_base::out | std::ios_base::binary};
    if (!fileMovies.is_open())
    {
        std::cerr << "Failed to open file" << std::endl;
        return -1;
    }

    std::string movieName{};
    std::getline(std::cin, movieName);

    std::string line{};
    line.reserve(256);

    long long int pos = fileMovies.tellp();
    for (line; std::getline(fileMovies, line);)
    {
        if (line.find(movieName) != std::string::npos)
            break;
        line.clear();
        pos = fileMovies.tellp();
    }

    if (fileMovies.eof())
    {
        std::cerr << "Failed to find the movie by name" << std::endl;
        return -1;
    }

    long long int curPos = fileMovies.tellp();

    // TODO: check format
    long long int commaPos = line.rfind(',');
    fileMovies.seekp(pos + commaPos + 2);

    int liked = 0;
    fileMovies >> liked;
    fileMovies.seekp(pos + commaPos + 2);
    fileMovies << ++liked;

    return 0;
}

输出:

PS C:\dev\builds\editfile\Release-Visual Studio\bin> cat .\sample.txt
SNO, Name, NoOfPeopleLiked
1, The Shawshank Redemption, 77
2, The Godfather, 20
3, Into The Wild, 35
4, The Dark Knight, 55
5, 12 Angry Men, 44
6, Schindler's List, 33
7, The Lord of the Rings: The Return of the King, 25
8, Pulp Fiction, 23
9, The Good, the Bad and the Ugly, 32
10, The Lord of the Rings: The Fellowship of the Ring, 56
PS C:\dev\builds\editfile\Release-Visual Studio\bin> .\main.exe
Angry
PS C:\dev\builds\editfile\Release-Visual Studio\bin> cat .\sample.txt
SNO, Name, NoOfPeopleLiked
1, The Shawshank Redemption, 77
2, The Godfather, 20
3, Into The Wild, 35
4, The Dark Knight, 55
5, 12 Angry Men, 45
6, Schindler's List, 33
7, The Lord of the Rings: The Return of the King, 25
8, Pulp Fiction, 23
9, The Good, the Bad and the Ugly, 32
10, The Lord of the Rings: The Fellowship of the Ring, 56

记住,你不能 在文件中间追加新字符(也不能删除它们)。您只能覆盖当前位置已有的。 因此,为了使其正常工作,您应该使用带有尾随空格的点赞数,或采用 0045 之类的格式。 另外,请注意您必须使用带有标志 in | out | binarystd::fstream。为了正确计算当前位置,二进制是必需的。