C++如何从TXT文件读取多条记录?现有代码修改方案
修复DVD记录读取问题:代码修改要点
我已通过文件操作创建了多条DVD记录,但无法读取文件中的全部数据。请告知需要修改以下代码中的哪些部分,才能打印出所有记录?说明:dvdTitle、artistName、dvdGenre为string类型,yearPurchased为int类型。
现有代码:
void addDvd() { cout << "Enter DVD Title\n"; cin >> this->dvdTitle; cout << "Enter Artists Name\n"; cin >> this->artistName; cout << "Enter Year Purchased\n"; cin >> this->yearPurchased; cout << "Enter DVD Genre\n"; cin >> this->dvdGenre; fstream DVDfile; DVDfile.open("DVD.txt", ios::app); DVDfile << "DVD Title: " << dvdTitle << endl << "Artist Name: " << artistName << endl << "Year Purchased: " << yearPurchased << endl << "DVD Genre: " << dvdGenre << endl << endl; } void displayDvd() { fstream DVDfile; DVDfile.open("DVD.txt", ios::in); while (!DVDfile.eof()) { cout << "DVD Title: " << dvdTitle << endl << "Artist Name: " << artistName << endl << "Year Purchased: " << yearPurchased << endl << "DVD Genre: " << dvdGenre << endl << endl; } }
核心问题分析
原displayDvd函数存在两个致命问题:
- 未从文件读取数据,仅循环打印成员变量的旧值,完全未利用文件内容
- 使用
!DVDfile.eof()作为循环条件,会导致最后一条记录重复输出,且无法正确判断读取结束
另外addDvd的输入逻辑有缺陷:cin >>读取字符串时会截断带空格的内容(比如"Fight Club"只能读入"Fight")。
代码修改要点
1. 重写displayDvd函数,添加文件读取逻辑
匹配写入时的文本格式,逐行读取并提取字段值,同时修正循环条件:
#include <string> #include <sstream> void displayDvd() { fstream DVDfile; DVDfile.open("DVD.txt", ios::in); if (!DVDfile.is_open()) { cout << "无法打开DVD记录文件!" << endl; return; } string line; // 循环读取每条完整记录 while (true) { // 读取DVD标题行 if (!getline(DVDfile, line) || line.substr(0, 11) != "DVD Title: ") break; dvdTitle = line.substr(11); // 读取艺术家名称行 if (!getline(DVDfile, line) || line.substr(0, 13) != "Artist Name: ") break; artistName = line.substr(13); // 读取购买年份行 if (!getline(DVDfile, line) || line.substr(0, 17) != "Year Purchased: ") break; yearPurchased = stoi(line.substr(17)); // 读取流派行 if (!getline(DVDfile, line) || line.substr(0, 11) != "DVD Genre: ") break; dvdGenre = line.substr(11); // 打印当前记录 cout << "DVD Title: " << dvdTitle << endl << "Artist Name: " << artistName << endl << "Year Purchased: " << yearPurchased << endl << "DVD Genre: " << dvdGenre << endl << endl; // 跳过记录之间的空行 getline(DVDfile, line); } DVDfile.close(); }
2. 优化addDvd的输入逻辑,支持带空格的字符串
改用getline读取文本,同时处理cin留下的换行符:
#include <limits> void addDvd() { cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清除之前输入的换行符 cout << "Enter DVD Title\n"; getline(cin, this->dvdTitle); cout << "Enter Artists Name\n"; getline(cin, this->artistName); cout << "Enter Year Purchased\n"; cin >> this->yearPurchased; cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清除年份输入后的换行符 cout << "Enter DVD Genre\n"; getline(cin, this->dvdGenre); fstream DVDfile; DVDfile.open("DVD.txt", ios::app); DVDfile << "DVD Title: " << dvdTitle << endl << "Artist Name: " << artistName << endl << "Year Purchased: " << yearPurchased << endl << "DVD Genre: " << dvdGenre << endl << endl; }
修改说明
- displayDvd修改核心:通过
getline逐行读取文件,匹配每行前缀后提取有效数据,将读取操作作为循环结束判断条件,避免eof()的缺陷。 - addDvd优化核心:解决
cin >>无法读取带空格字符串的问题,支持输入完整的标题和艺术家名称。 - 增加文件打开判断:避免文件不存在或权限不足时的程序异常。
内容的提问来源于stack exchange,提问作者Syed Irfan Ali Shah
相关产品推荐
相关产品推荐

