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

C++程序读取文件时vector未正确写入信件数据求助

文件读取异常排查:vector未加载数据问题

问题概述

后续需对存储letter类的vector进行排序,但当前读取文件时vector未写入任何数据,仅读取到用户邮箱的第一行。以下是相关代码及数据文件,需排查流读取或输出环节的问题。

头文件(class.h)

#ifndef CLASS_H
#define CLASS_H

#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct date {
    int day{ 1 };
    int month{ 1 };
    int year{ 1999 };

    date(int day, int month, int year) {
        this->day = day;
        this->month = month;
        this->year = year;
    }

    date() = default;

    friend istream& operator>>(istream& is, date& date) {
        is >> date.day >> date.month >> date.year;
        return is;
    }

    friend ostream& operator<<(ostream& os, const date& date) {
        os << date.day << "." << date.month << "." << date.year;
        return os;
    }
};

class letter {
public:
    string sender{ "None" };
    string message;
    date when;

    string Get_sender() {
        return sender;
    }

    string Get_message() {
        return message;
    }

    date Get_date() {
        return when;
    }

    letter() = default;

    letter(string sender, string message, date when)
        : sender(sender), message(message), when(when) {}

    friend istream& operator>>(istream& is, letter& mes) {
        is >> mes.sender;
        char quote;
        is >> ws >> quote;
        getline(is, mes.message, '"');
        is >> mes.when;
        return is;
    }

    friend ostream& operator<<(ostream& os, const letter& letterObj) {
        os << "Sender: " << letterObj.sender << endl;
        os << "Message: " << letterObj.message << endl;
        os << "Date: " << letterObj.when << endl;
        return os;
    }
};

class Email {
public:
    vector<letter> letters;
    string userName{ "None" };

    friend istream& operator>>(istream& is, Email& mail) {
        is >> mail.userName;
        return is;
    }

    friend ostream& operator<<(ostream& os, const Email& mail) {
        os << "User name: " << mail.userName << endl;
        os << "Vector letters:" << endl;
        for (const letter& letterObj : mail.letters) {
            os << letterObj << endl;
        }
        return os;
    }
};

#endif // !CLASS_H

main.cpp

#include <iostream>
#include "class.h"
#include <string>
#include <windows.h>
#include <fstream>
#include <vector>
using namespace std;

int main() {
    char FileName[100];
    cout << "Which file should I enter data from?\n";
    cin.getline(FileName, sizeof(FileName));
    ifstream fin(FileName);
    Email email;
    if (fin.is_open()) {
        fin >> email;
        letter temp;
        while (fin >> temp) {
            email.letters.push_back(temp);
        }
        fin.close();
        cout << email << endl;
        cout << "Which file should I output the data to?\n";
        cin.getline(FileName, sizeof(FileName));
        ofstream fout(FileName);
        if (fout.is_open())
        {
            fout << email;
            fout.close();
            cout << "Data output to file " << FileName << endl;
        }
        else
        {
            cout << "Error writing to file " << FileName << endl;
        }
    }
    else
    {
        cout << "File " << FileName << " not found\n";
    }

    Sleep(7654);
    return 0;
}

data.txt

mymail5@pochta.com 
danila@pochta.com "I love my mom" 17.08.2023 
gleb@pochta.com "HABIBATI" 13.09.2024 
ImFromChina@pochta.com "This is my 4720 year!" 31.12.4719 

问题根源

  1. 日期读取逻辑错误:date类的operator>>直接尝试读取三个整数,但data.txt中的日期格式为dd.mm.yyyy,包含.分隔符。当读取到.时,流无法将其解析为整数,导致流进入错误状态,后续所有读取操作(包括letter的循环读取)全部终止,最终vector无数据。
  2. 潜在的流残留问题:读取letter的message后,流中可能残留未处理的空白字符,但核心问题仍为日期读取失败导致的流异常。

修复方案

1. 修正date类的输入运算符

修改date的operator>>,处理.分隔符,确保正确解析日期:

friend istream& operator>>(istream& is, date& date) {
    char dot1, dot2;
    // 读取日、跳过点、读取月、跳过点、读取年
    is >> date.day >> dot1 >> date.month >> dot2 >> date.year;
    // 可选:验证分隔符是否为'.',增强鲁棒性
    if (dot1 != '.' || dot2 != '.') {
        is.setstate(ios::failbit); // 设置流错误状态
    }
    return is;
}

2. 优化letter的读取逻辑(可选)

在读取完message后,显式跳过剩余的空白字符(包括换行),避免影响后续日期读取:

friend istream& operator>>(istream& is, letter& mes) {
    is >> mes.sender;
    char quote;
    is >> ws >> quote;
    if (quote != '"') { // 验证是否为双引号
        is.setstate(ios::failbit);
        return is;
    }
    getline(is, mes.message, '"');
    is >> ws; // 跳过消息后的空白
    is >> mes.when;
    return is;
}

验证效果

修正后,重新运行程序,data.txt中的letter数据会被正确读取到vector中,输出时能显示所有信件内容,后续可正常进行排序操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 12:52:04