You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

关键改动说明

  1. 用vector<string>代替裸指针:避免手动管理内存,彻底解决悬垂指针问题,vector会自动负责内存的分配和释放。
  2. 添加完整的错误检查:检查命令行参数数量、文件是否打开成功、读取操作是否有效,能快速定位问题。
  3. 修正多对象创建逻辑:根据传入的n创建对应数量的pledge对象,符合需求。
  4. 使用ifstream代替fstream:只读文件场景下更语义化,减少不必要的操作。

内容的提问来源于stack exchange,提问作者Moe98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:52:52