Fstream无法正常读取文件的技术问题求助
你的代码里看似是fstream读取问题,其实核心是悬垂指针导致的未定义行为,加上缺少文件读取的错误检查,具体问题和修复如下:
问题1:悬垂指针导致非法内存访问
在createPledges函数里,你定义了局部数组string vote[5],然后把它的地址传给p->vote。函数执行完后,这个局部数组会被栈销毁,p->vote就变成了指向无效内存的悬垂指针。后续在main里访问p->vote[0]时,行为是未定义的——有时候可能看似能输出,有时候会崩溃或者输出乱码,这和你描述的“有时异常有时正常”的现象吻合。
问题2:缺少文件读取的错误检查
你没有检查input.open(filename)是否成功,如果文件路径错误、权限不足,fstream会处于失败状态,getline读取不到内容,这也会导致看似读取失败的问题。
问题3:逻辑不符预期
你传入的参数n应该是要创建的pledge数量,但当前代码只创建了一个pledge对象,没有用到n,这和你的需求不符。
修复后的代码示例
#include <iostream> #include <fstream> #include <string> #include <vector> using namespace std; class pledge { public: string name; vector<string> vote; // 用vector代替指针,自动管理内存 void setName(string n) { name = n; } void setVote(const vector<string>& v) { vote = v; } void printName() { cout << name << endl; } void printVote() { if (!vote.empty()) cout << vote[0] << "\n\n"; } void print() { cout << name << ": "; for (size_t i = 0; i < vote.size(); ++i) { cout << vote[i]; if (i != vote.size() - 1) cout << ", "; } cout << endl; } }; vector<pledge> createPledges(const string& filename, int n); int main(int argc, char *argv[]) { if (argc != 3) { // 先检查参数数量是否正确 cerr << "用法: 程序名 文件名 人数" << endl; return 1; } int n = stoi(argv[2]); vector<pledge> pledges = createPledges(argv[1], n); // 测试输出 for (auto& p : pledges) { p.print(); } } vector<pledge> createPledges(const string& filename, int n) { ifstream input(filename); // 用ifstream代替fstream,更适合只读操作 if (!input.is_open()) { // 检查文件是否成功打开 cerr << "无法打开文件: " << filename << endl; return {}; } vector<pledge> pledges; pledges.reserve(n); // 预分配内存,提升效率 for (int i = 0; i < n; ++i) { pledge p; string name; vector<string> votes(5); // 存储5项投票内容 // 读取姓名(假设文件中每行先存姓名,然后是5行投票内容) if (!getline(input, name)) break; // 读取失败就退出循环 p.setName(name); // 读取5项投票内容 for (int j = 0; j < 5; ++j) { if (!getline(input, votes[j])) { // 如果文件内容不足,填充空字符串或者处理错误 votes[j] = ""; } } p.setVote(votes); pledges.push_back(p); } input.close(); return pledges; }
关键改动说明
- 用
vector<string>代替裸指针:避免手动管理内存,彻底解决悬垂指针问题,vector会自动负责内存的分配和释放。 - 添加完整的错误检查:检查命令行参数数量、文件是否打开成功、读取操作是否有效,能快速定位问题。
- 修正多对象创建逻辑:根据传入的
n创建对应数量的pledge对象,符合需求。 - 使用
ifstream代替fstream:只读文件场景下更语义化,减少不必要的操作。
内容的提问来源于stack exchange,提问作者Moe98
相关产品推荐
相关产品推荐

