C++使用fstream操作txt文件 无法删除vector对应元素问题求助
问题排查与解决方案
首先明确:代码无法删除元素、内容存储异常和ios::trunc的使用无关,核心是逻辑流程错误,具体问题如下:
- 核心逻辑错误1:未加载历史数据到内存
每次启动程序时,vector<string> Names都是空的,虽然更新后的代码读取了practiceFile.txt的内容打印,但没有把读取到的每行内容存入Names容器,后续删除操作操作的是空容器,自然无法生效;最后写临时文件时也只会写入本次操作新增的少量内容,会直接覆盖掉所有历史数据。 - 逻辑冲突:重复写文件导致内容错乱
你同时执行了两个矛盾操作:用ios::app模式打开原文件追加写入本次操作的内容,后面又把仅包含本次操作内容的临时文件覆盖原文件,最终文件里只会残留本次操作的内容,历史数据全部丢失。 - 遍历删除元素的写法错误
正序遍历vector用erase删除元素时,删除元素后后续元素会自动前移,会导致下一次遍历跳过相邻元素,应该用迭代器遍历或者倒序遍历。 - 头文件、命名冲突问题
用到了std::find但是没有包含<algorithm>头文件,部分编译器会编译失败;变量名remove和C标准库的remove()函数重名,可能引发未定义行为。
正确实现流程
- 程序启动后先读取原文件的所有学生姓名,完整存入
Names容器 - 接收用户操作,对内存中的
Names容器做新增/删除操作 - 操作完成后,直接将完整的
Names容器写入临时文件,再用临时文件覆盖原文件即可,不需要提前对原文件做追加操作
修正后可运行代码
#include <iostream> #include <string> #include <vector> #include <fstream> #include <algorithm> #include <cstdlib> using namespace std; void Menu() { cout << "******************" << endl; cout << "1 - Add student" << endl; cout << "2 - Delete student" << endl; cout << "3 - All students" << endl; cout << "******************" << endl; } struct School { string Name; string removeName; int Option; }; int main() { School Students; vector<string> Names; // 加载历史数据到容器 ifstream inFile("practiceFile.txt"); string line; while (getline(inFile, line)) { if (!line.empty()) { Names.push_back(line); } } inFile.close(); Menu(); cout << endl << "Option: "; cin >> Students.Option; cin.ignore(); if (Students.Option == 1) { cout << "Enter name: "; getline(cin, Students.Name); Names.push_back(Students.Name); } else if (Students.Option == 2) { cout << "Enter name to delete: "; getline(cin, Students.removeName); auto it = find(Names.begin(), Names.end(), Students.removeName); if (it != Names.end()) { Names.erase(it); cout << "Deleted successfully" << endl; } else { cout << "Name not found" << endl; } } else if (Students.Option == 3) { cout << "All students:" << endl; for (const auto& name : Names) { cout << name << endl; } return 0; } // 全量写入临时文件 ofstream TempFile("practiceFile_temp.txt", ios::trunc); if (TempFile.is_open()) { for (const auto& name : Names) { TempFile << name << endl; } } TempFile.close(); // 覆盖原文件 remove("practiceFile.txt"); rename("practiceFile_temp.txt", "practiceFile.txt"); return 0; }
内容的提问来源于stack exchange,提问作者Gaspar
相关产品推荐
相关产品推荐

