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
问题根源
- 日期读取逻辑错误:
date类的operator>>直接尝试读取三个整数,但data.txt中的日期格式为dd.mm.yyyy,包含.分隔符。当读取到.时,流无法将其解析为整数,导致流进入错误状态,后续所有读取操作(包括letter的循环读取)全部终止,最终vector无数据。 - 潜在的流残留问题:读取
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
相关产品推荐
相关产品推荐

