【问题标题】:Deleting a line from c++ file by giving a word通过给出一个单词从c ++文件中删除一行
【发布时间】:2020-03-26 00:40:06
【问题描述】:

我制作了一个 Quizlet 代码,将一个单词及其翻译(俄语)保存在 csv 文件中。 所以,'add' 和 'read' 函数完美地工作,但是当我给出该行的子字符串时,我一直试图让 'delete' 函数删除该行。

更新:我正在尝试将除我要删除的行之外的所有行复制到一个新文件中,然后重命名它。 但是当新文件创建时,它是空的!

例如:在文件中,第 1 行:apple яблоко。

输入:apple,然后整个被删除。

这是我的代码:我只是在 void quizlet::DeleteWord() 中遇到问题

#include <string>
#include <iostream>
#include <vector>
#include<fstream>
#include <sstream>
#include<cstdlib>
using namespace std;

class quizlet {
private:
    std::string filename;
    std::vector<std::string> lines;

public:
    quizlet(std::string filename) : filename(filename) {}

    void AddWord(std::string, std::string);
    vector<string> ReadAllWords();
    void DeleteWord();
};

void quizlet::AddWord(std::string word, std::string translation) {
   cout << "Write a word and its translation separated by a space:" << std::endl;
   cin >> word >> translation;


   // file pointer
    fstream fout;

    // opens an existing csv file or creates a new file.
    fout.open("words.txt",ios::out | ios::app);
    // Insert the data to file
    fout <<word<<" "<<translation<<endl;

    std::cout << "Saved new card: " << word << "/" << translation << std::endl;
}

vector<string> quizlet::ReadAllWords() {

    // File pointer
    fstream fin;

    // Open an existing file
    fin.open("words.txt", ios::in);




    // Read the Data from the file
    // as String Vector
    vector <string> rows;
    string line, word, temp;


    while (getline(fin, line)) {

        cout << line << std::endl;
        rows.push_back(line);
        stringstream s(line);

    }

    return rows;







   }


void quizlet::DeleteWord() {

    string line;
    fstream fin;
    fstream fout;
    fin.open("words.txt", ios::in);
    fout.open("new.txt",ios::out | ios::app);
    string token;
    cin>>token;

    vector <string> lines;
    while (getline(fin, line)) {
        if (line.find(token) != string::npos) {
            cout << line << endl;
            fin << line << endl;
            cout<<"the line has been deleted!";
            //remove (line);
        }
    }

    fin.close();
    fout.close();
    remove("words.txt");
    rename("new.txt", "words.txt");
    cout << "\nChanges has Successfully been made...... Data Saved\n" << endl;

}




int main() {
    auto Quizlet = quizlet("words.txt");
    string word, translation;
    while (true) {
        std::string command;
        std::cin >> command;



        if (command == "add") {

            Quizlet.AddWord(word, translation);

        } else if (command == "read") {
            Quizlet.ReadAllWords();

        }
        else if (command == "delete") {
            Quizlet.DeleteWord();

        }



        else {
            return 0;
        }
    }
}

【问题讨论】:

  • 您的编辑以某种方式杀死了语法突出显示...而不是std::vector&lt;std::string&gt; words;,存储一个向量行,例如std::vector&lt;std::string&gt; lines; 这样你就需要遍历你的向量,检查当前单词是否是line 的子字符串,然后在该行上使用vector.erase() 将其删除。您始终可以通过创建行的stringstream 并在需要时使用逗号分隔符调用getline 从任何行中获取每个单词。
  • 不需要调用stringstream,你也可以从vector的迭代器中获取字符串,然后使用像erase这样的std::string函数将新的字符串存回vector中
  • (注意:如果你依赖```来提供固定格式,你必须在```后面加上语言类型来获得语法高亮,例如```c++ 。如果您将所有内容缩进 4 个空格,您将获得自动语法高亮显示。)

标签: c++ file csv


【解决方案1】:

好吧,在尝试了很长时间之后。 我得到了这段代码,它运行良好,没有错误。

谢谢大家!

#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstdlib>

using namespace std;

class quizlet {
private:
    std::string filename;
    std::vector<std::string> lines;

public:
    quizlet(std::string filename) : filename(filename) {}

    void AddWord(std::string, std::string);
    vector<string> ReadAllWords();
    void DeleteWord(std::string);
};

void quizlet::AddWord(std::string word, std::string translation) {
   cout << "Write a word and its translation separated by a space:" << std::endl;
   cin >> word >> translation;

   // file pointer
    fstream fout;

    // opens an existing csv file or creates a new file.
    fout.open("words.txt",ios::out | ios::app);
    // Insert the data to file
    fout << word << " " << translation << endl;

    std::cout << "Saved new card: " << word << "/" << translation << std::endl;
}

vector<string> quizlet::ReadAllWords() {

    // File pointer
    fstream fin;

    // Open an existing file
    fin.open("words.txt", ios::in);

    // Read the Data from the file
    // as String Vector
    vector <string> rows;
    string line, word, temp;

    while (getline(fin, line)) {
        cout << line << std::endl;
        rows.push_back(line);
        stringstream s(line);
    }
    return rows;
}

void quizlet::DeleteWord(string token) {
    string line;
    fstream fin;
    fstream fout;
    fin.open("words.txt", ios::in);
    fout.open("new.txt",ios::out | ios::app);

    cin >> token;

    vector<string> lines;
    while(getline(fin, line)) {
        if(line.find(token) == string::npos)  {
            fout << line << endl;
        }
    }
    fout.close();
    fin.close();

    remove("words.txt");
    rename("new.txt", "words.txt");
    cout << "\nChanges has Successfully been made...... Data Saved\n" << endl;

}

int main() {
    auto Quizlet = quizlet("words.txt");
    string word, translation, token;
    while(true) {
        std::string command;
        std::cin >> command;

        if(command == "add") {
            Quizlet.AddWord(word, translation);
        } else if(command == "read") {
            Quizlet.ReadAllWords();
        } else if(command == "delete") {
            Quizlet.DeleteWord(token);
        } else {
            return 0;
        }
    }
}

【讨论】:

    【解决方案2】:

    更新后编辑:

    鉴于您正在尝试做的事情,我的原始答案现在更有意义。您应该一次读取整个文件,在内存中进行任何您想要的添加和删除,然后用整个新列表覆盖原始文件。

    原答案:

    考虑通过std::map&lt;std::string,std::wstring&gt; 而不是文件中行的std::vector&lt;std::string&gt; 将文件读入内存。

    使用这种方法,添加和删除一个单词及其翻译都很简单。

    添加:

    //if-guard only needed if you want to protect against overwriting already-existing words.
    auto found_iter = cards.find(word);
    if(found_iter == cards.end()) {
        cards.insert_or_assign(word, translation);
    }
    

    删除:

    auto found_iter = cards.find(word);
    if(found_iter != cards.end()) {
        cards.erase(found_iter);
    }
    

    将它写回文件就像循环遍历集合一样简单:

    for(const auto& [word,translation] : cards) {
        fout << word << ' ' << translation << '\n';
    }
    fout.close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 2021-09-06
      • 1970-01-01
      相关资源
      最近更新 更多