读文件问题?
这是我做的一个简单的职工管理系统,只有增加信息,显示职工信息,和文件读取和储存功能。。
当第一次进入系统增加一名员工信息,然后按显示,能显示出一名员工信息,保存文件 ,退出。
再次进入系统,显示员工信息却显示了两名员工的信息,一个系空白的,不知道哪里出了点小问题,,
#include "an.h"
int main()
{
int a,quite=0;
cout<<"\t\t◎★★★★【 欢迎进入职工信息管理系统 】★★★★◎"<<endl;
read();
cout<<"按任意键开始……";
getch();
while(!quite)
{
mainmenushow();
int x=0;
cin>>a;
switch(a)
{
case 1:
{
sonmenu4show();
while(!x)
{
sonmenu4show();
cin>>a;
switch(a)
{
case 1: { add(); } break;
case 2: {save();getch(); } break;
case 3: { x=1; } break;
case 4: { display();getch();} break;
default: cout<<"输入错误!"; break;
}
}
} break;
case 2:
{
read(); getch();
} break;
case 3:
{
quite=1;
} break;
default: cout<<"输入错误!";break;
}
}
return 0;
}
void add( )
{
//link*p=NULL;
cout<<"\t\t请输入员工号:\t" ;
cin>>end->work.num;cout<<endl<<endl;
/*if(p=find_num(end->work.num))
{
cout<<"\t\t该工号已经存在!请从新输入员工号:"; goto t1;
}t1:
*/
cout<<"\t\t请输入员工姓名:\t"; cin>>end->work.name;cout<<endl<<endl;
end->next=new link;
end=end->next;
cout<<"\t\t按任意键继续.";
getch();
}
/*
void cancle()
{
char name[256];
link*p2;
cout<<"\t\t请输入你想删除的员工: ";
t1:cin>>name;
if(NULL==find_name(name))
{
cout<<"\t\t该员工不存在!! 请从新输入: " ;goto t1;
}
else
{
p2=find_name(name);
p2->next=p2->next->next;
}
}
link *find_num(char*p)
{
for(link*p3=head;p3!=end;p3=p3->next)
{
if(!strcmp(p3->next->work.num,p))
{
return p3;
}
}
return NULL;
}
link *find_name(char*p)
{
for(link*p3=head;p3->next!=end;p3=p3->next)
{
if(!strcmp(p3->next->work.name,p))
{
return p3;
}
}
return NULL;
}
*/
void read() //读取文件数据
{
head=new link;
head->next=new link;
end=head->next;
ifstream in;
in.open("worker.dat",ios::binary);
if(!in)
{
cout<<"\t\t这是个新系统,欢迎使用...."<<endl;
}
else
{
// in.seekg(ios::beg);
while(!in.eof())
{
in>>end->work.num>>end->work.name;
end->next=new link;
end=end->next;
}
in.close();
cout<<"\t\t读取信息成功!。。";
}
}
void save() //保存到文件
{
ofstream out("worker.dat",ios::binary);
for(link*p=head->next;p!=end;p=p->next)
{
out<<p->work.num<<"\t"<<p->work.name<<endl;
}
out.close();
cout<<"保存成功!!!";
}
/*
void fang1()
{
save();
for(link * temp;head->next!=end;)
{
temp=head->next;
head->next=head->next->next;
delete temp;
}
delete head,end;
}
*/
void sonmenu1show()
{
system("cls");
cout<<"\t+----------------------------+\n"<<
"\t+ +\n"<<
"\t+ 职工管理系统 +\n"<<
"\t+ +\n"<<endl<<endl;
}
void sonmenu4show()
{
system("cls");
cout<<"\t+----------------------------+\n"<<
"\t+ +\n"<<
"\t+ 职工管理系统 +\n"<<
"\t+ +\n"<<
"\t+----------------------------+\n"<<endl;
cout<<"\t 1.增加员工 \n"<<
"\t 4.显示员工 \n"<<
"\t 2.保存数据 \n"<<
"\t 3.退出 \n"<<
"\t 请选择: " ;
}
void mainmenushow()
{
system("cls");
cout<<"\t+--------------------------+\n"<<
"\t+ +\n"<<
"\t+ 职工管理系统 +\n"<<
"\t+ +\n"<<
"\t+--------------------------+\n"<<
"\t 1.职工管理 \n"<<
"\t 2.初始化系统 \n"<<
"\t 3.退出系统 \n"<<
"\t 请选择: ";
}
void display() //显示员工信息
{
for(link*p=head->next;p!=end;p=p->next)
{
cout<<"\t\t员工号:"<<p->work.num<<endl<<"\t\t员工姓名:"<<p->work.name<<endl;
}
}
头文件以下:
#include<iostream>
#include <conio.h >
using namespace std;
#include <fstream>
#define MAX 20
typedef struct
{
char num[MAX];
char name[MAX];
}worker;
typedef struct lin
{
worker work;
struct lin *next;
}link;
link *head,*end;
void add();
link *find_num(char*p);
link *find_name(char*p);
void save();
void read();
void sonmenu4show();
void mainmenushow();
void display();
void sonmenu1show();
void fang1();
/*
link *create();
int display();
int sort();
int cancle(char *p);
int free(link *p);
int count();
*/
[解决办法]
摒弃fstream
使用FILE *
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
whlie (!feof(f)) {
a=fgetc(f);
//...
b=fgetc(f);//可能此时已经feof了!
//...
}
而这样写就没有问题:
whlie (1) {
a=fgetc(f);
if (feof(f)) break;
//...
b=fgetc(f);
if (feof(f)) break;
//...
}
类似的例子还可以举很多。