手机通讯录系统遇见的一些问题:
1.scanf("%s",s ); 遇到空白字符,包括空格,制表符,换行符时均会停止输入
故换 使用gets( );能够接受空格,但是会以回车作为结束符
scanf()函数读取数字,字符,字符串的时候,都会遗留一个换行符在缓冲区,但是它不读取换行符(输入数字时空白符都不读),因为不读所以遗留在了缓冲区。gets会读取别人留在缓冲区内的换行符并显示,导致数据读取少一个,原因是回车被存在缓冲区内。
因此,每次输入完一个函数都要清空缓冲区
(1)在scanf( );后面再加一个的getchar(),用于接收回车,并丢弃。
(2)在scanf( );后面加fflush(stdin);清空缓冲区。注:高等vs不适用
使用fflush(stdin) ;读取标准输入时在遇到回车时会直接回车之前包括回车都读出到指定的变量中
(3)万能法:在scanf( );后面加一个
while (getchar() != '\n')
{
;
}
2.使用feof,文件读入会多读一次
while(!feof(fp))
{
fread(buf,1,100,fp);
//dosomthing
}
原因是feof( );特点:先读,根据读的位置来结束位置标志,然后根据标志位判断是否结束
改进方法:
法一:
while(1)
{
fread(buf,1,100,fp);
if(feof(fp))
break;
//dosomething
}
法二:
while(1)
{
if(fread(buf,1,100,fp)<1)
break;
//dosomething
}
3.文件保存和读取的两种方法:
void SaveToFile(linklist head)//将信息存入文件
{
FILE *fp ;
node *p1;
fflush(stdin);//用于清空缓存
fp = fopen("member","wb");
p1=head->next;
if(!fp)
{
printf("打开文件失败!\n");
exit(0);
}
while(p1!=NULL)
{
// fprintf(fp,"序号\t姓名\t号码\t类型\t\n");
// fprintf(fp,"%s\t%s\t%s\t%s\n",p1->num,p1->name,p1->tel,p1->type);
fwrite(p1,sizeof(node),1,fp);
p1=p1->next;
}
printf("保存成功");
fclose(fp);
}
linklist LoadFromFile( )//从文件中读取
{
FILE *fp;
node *r,*p;
fp = fopen("member", "rb");
if(!fp)
{
printf("文件还没有创建,请手工输入信息并保存吧!\n");
exit(0);
}
r=head=(node*)malloc(sizeof(node));
p=head->next;
while(1)
{
p=(node*)malloc(sizeof(node));
//fscanf(fp,"序号\t姓名\t号码\t类型\t");
//fscanf(fp,"%s%s%s%s",p->num ,p->name ,p->tel ,p->type );
//if(feof(fp))
if(fread(p,sizeof(node),1,fp)<1)
break;
r->next=p;
r=p;
}
r->next=NULL;
free(p);
printf("文件读取完毕!\n");
fclose(fp);
}
4.附加函数部分:
链表的冒泡排序:
void BubbleSort(linklist head)
{
node *f, *p, *x, *y;
f = NULL;
//判断是否只有一个元素或者没有元素
if(head -> next == NULL || head -> next -> next == NULL)
{
return;
}
while(f != head->next->next)
{
for(p = head; p -> next -> next != f; p = p -> next)
{
if(p -> next -> data > p -> next -> next ->data)
{
x = p -> next;
y = p -> next -> next;
p -> next = y;
x -> next = y -> next;
y -> next = x;
}
}
f = p -> next;
}
}