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

C++电话簿程序Case 2无法执行:无法显示文件存储数据求助

问题分析与解决方案

你的电话簿程序中选项2无法显示数据,核心原因是文件打开模式不正确,导致你根本无法向phone.dat中写入数据,自然也就读不到任何内容。下面详细拆解问题并给出修复方案:

1. 最关键的问题:文件打开模式错误

在main函数开头,你用以下方式打开文件:

file.open("phone.dat", ios::in | ios::binary);

ios::in模式只允许读取文件,不支持写入操作。当你选择选项1添加新记录时,file.write((char *)&rec, sizeof(rec))会执行失败,数据根本没被写入到phone.dat里,所以选项2自然看不到任何记录。

你需要修改打开模式,同时支持读写,并且如果文件不存在则创建它:

// 先尝试打开,若不存在则创建
file.open("phone.dat", ios::in | ios::out | ios::binary);
if (!file) {
    // 文件不存在,重新打开为写入模式创建文件
    file.open("phone.dat", ios::out | ios::binary);
    file.close();
    // 再以读写模式打开
    file.open("phone.dat", ios::in | ios::out | ios::binary);
}

2. 选项2的循环逻辑优化

当前选项2的循环写法有潜在冗余问题:

while(file)
{
 file.read((char *)&rec, sizeof(rec));
 if(!file.eof()) rec.showdata();
}

这种写法会在文件末尾时多读一次(虽然你加了!file.eof()判断避免显示无效数据),更简洁可靠的写法是把read操作放在循环条件中:

file.seekg(0, ios::beg);
cout<<"\n\nRecords in Phone Book\n";
phoneBook tempRec; // 用临时变量避免覆盖原rec
while(file.read((char *)&tempRec, sizeof(tempRec)))
{
    tempRec.showdata();
}
file.clear();
getch();

这样只有当read成功读取到完整对象时,才进入循环显示数据,逻辑更清晰直观。

3. 其他细节修复

  • 选项5中的缓冲区问题:在读取用户输入新电话号码前,cin.get(ch)可能无法正确清除换行符,建议用cin.ignore()替代(需要包含<limits>头文件):
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout<<"Enter New Telephone No : ";
    cin>>telno;
    
  • 程序退出时关闭文件:当前只有选择默认选项时才会关闭文件,建议在case 6中添加file.close();,确保文件资源被正确释放。
  • telno数组长度问题:你定义telno[6],但电话号码通常不止5位(加上终止符),建议改为telno[15],和类中的phno[15]保持一致,避免字符串截断。

修正后的完整代码(关键部分修改)

//Telephone Directory
#include <iostream>
#include <fstream>
#include <string.h>
#include <iomanip>
#include <conio.h>
#include<stdlib.h>
#include <limits> // 用于cin.ignore
using namespace std;

class phoneBook{
 char name[20],phno[15];
 public:
 void getdata();
 void showdata();
 char *getname(){ return name; }
 char *getphno(){ return phno; }
 void update(char *nm,char *telno){ strcpy(name,nm); strcpy(phno,telno); }
};

void phoneBook :: getdata(){
 cout<<"\nEnter Name : ";
 cin>>name;
 cout<<"Enter Phone No. : ";
 cin>>phno;
}

void phoneBook :: showdata(){
 cout<<"\n";
 cout<<setw(20)<<name;
 cout<<setw(15)<<phno;
}

int main(){
 phoneBook rec;
 fstream file;
 // 修正文件打开逻辑
 file.open("phone.dat", ios::in | ios::out | ios::binary);
 if (!file) {
     file.open("phone.dat", ios::out | ios::binary);
     file.close();
     file.open("phone.dat", ios::in | ios::out | ios::binary);
 }
 char ch,nm[20],telno[15]; // 修正telno长度
 int choice,found=0;
 int cnt=0;
 while(1)
 {
 system("cls");
 cout<<"\n*****Phone Book*****\n";
 cout<<"1) Add New Record\n";
 cout<<"2) Display All Records\n";
 cout<<"3) Search Telephone No.\n";
 cout<<"4) Search Person Name\n";
 cout<<"5) Update Telephone No.\n";
 cout<<"6) Exit\n";
 cout<<"Choose your choice : ";
 cin>>choice;
 switch(choice)
 {
 case 1 : //New Record
 rec.getdata();
 cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 替换cin.get(ch)
 file.write((char *)&rec, sizeof(rec));
 break;
 case 2 : //Display All Records
 file.seekg(0,ios::beg);
 cout<<"\n\nRecords in Phone Book\n";
 phoneBook tempRec;
 while(file.read((char *)&tempRec, sizeof(tempRec)))
 {
     tempRec.showdata();
 }
 file.clear();
 getch();
 break;
 case 3 : //Search Tel. no. when person name is known.
 cout<<"\n\nEnter Name : ";
 cin>>nm;
 file.seekg(0,ios::beg);
 found=0;
 while(file.read((char *) &rec, sizeof(rec)))
 {
 if(strcmp(nm,rec.getname())==0)
 {
 found=1;
 rec.showdata();
 }
 }
 file.clear();
 if(found==0) cout<<"\n\n---Record Not found---\n";
 getch();
 break;
 case 4 : //Search name on basis of tel. no
 cout<<"\n\nEnter Telephone No : ";
 cin>>telno;
 file.seekg(0,ios::beg);
 found=0;
 while(file.read((char *) &rec, sizeof(rec)))
 {
 if(strcmp(telno,rec.getphno())==0)
 {
 found=1;
 rec.showdata();
 }
 }
 file.clear();
 if(found==0) cout<<"\n\n---Record Not found---\n";
 getch();
 break;
 case 5 : //Update Telephone No.
 cout<<"\n\nEnter Name : ";
 cin>>nm;
 file.seekg(0,ios::beg);
 found=0;
 cnt=0; // 重置cnt,避免多次查询导致累计
 while(file.read((char *) &rec, sizeof(rec)))
 {
 cnt++;
 if(strcmp(nm,rec.getname())==0)
 {
 found=1;
 break;
 }
 }
 file.clear();
 if(found==0) cout<<"\n\n---Record Not found---\n";
 else
 {
 int location = (cnt-1) * sizeof(rec);
 cin.ignore(numeric_limits<streamsize>::max(), '\n');
 cout<<"Enter New Telephone No : ";
 cin>>telno;
 file.seekp(location);
 rec.update(nm,telno);
 file.write((char *) &rec, sizeof(rec));
 file.flush();
 }
 break;
 case 6 : 
 file.close(); // 关闭文件
 return 0;
 default: 
 file.close();
 cout<<"Invalid choice!";
 getch();
 }
 }
}

现在你可以测试修改后的程序:添加几条记录后,选择选项2就能正常显示所有数据了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:56:07