关于文件读写的几点学习记录
1. 各函数的简单理解
2. 写文件过程中遇到的坑
下面这段代码是找出1~10000之间的素数并保存到文件中。在使用fscanf读取文件的过程中我遇到了几个问题:
1、空文件时如何判断文件结束(文本文件可以直接用feof,对于二进制文件而言可以int ch,读入数据前令ch=fgetc(fp),若ch=EOF,则文件为空)
2、在使用fscanf读数据时发现它的返回值总为-1,即没有分配给它数据,后来发现要再次打开文件,“w”只写,再用“r”打开一遍就行了。
3、fscanf遇到空格、换行停止,坑的一批
4、这代码有问题
5.写下面这块代码遇到的问题主要是二进制文件的读取,如何跳跃读取(移动指针),算是投机取巧绕过了这个问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN sizeof(struct LOG)//LEN=56;
int n;
struct LOG{
char number[20];
char name[20];
float score;
struct LOG *next;
}store[100];
FILE *openfile(char *name,char *openmode);
struct LOG *creat(struct LOG *head);
int input(struct LOG *p);
void write(struct LOG *head);
void read(struct LOG *head);
void rank(struct LOG *head);
int main(){
struct LOG *head,*p;
head=creat(head);
p=head;
do{
printf("%s %s %.1f\n",p->number,p->name,p->score);
p=p->next;
}while(p!=NULL);
write(head);
read(head);
rank(head);
return 0;
}
struct LOG *creat(struct LOG *head){
struct LOG *p1,*p2;
p1=(struct LOG *)malloc(LEN);
p2=p1;
while(input(p1)!=-1){
n++;
if(n==1)head=p1;
p2=p1;
p1=(struct LOG *)malloc(LEN);
p2->next=p1;
}
free(p1);p2->next=NULL;
return (head);
}
void write(struct LOG *head){
FILE *fp;
struct LOG *p;
fp=openfile("student.dat","wb+");
p=head;
while(p!=NULL){
fwrite(p,LEN,1,fp);
p=p->next;
}
fclose(fp);
}
void read(struct LOG *head){
FILE *fp;
struct LOG *p;
int i=0,ch=0;
fp=openfile("student.dat","rb");
float max=-999,sum=0;
p=head;
while(ch!=EOF){ //通过读取字符判断是否到达文件末尾
fseek(fp,LEN*i++,0);
fread(p,LEN,1,fp);
if(p->score>max)max=p->score;
sum += p->score;
ch=fgetc(fp);
}
printf("max=%.1f\naverage=%.1f\n",max,sum/n);
fclose(fp);
}
void rank(struct LOG *head){
FILE *fp,*cfptr;
struct LOG *p;p=head;
float mid;
int j,i=0,mid0;
char str1[20],str2[20];
i=0;fp=openfile("student.dat","rb");cfptr=openfile("score.txt","a");
while(p!=NULL){
fread(p,LEN,1,fp);
store[i].score=p->score;
strcpy(store[i].name,p->name);
strcpy(store[i].number,p->number);
// printf("%f",score_1[i]);
p=p->next;
i++;
}
for(i=0;i<n;i++){
for(j=i;j<n;j++){
if(store[i].score<store[j].score){
mid=store[i].score;strcpy(str1,store[i].number);strcpy(str2,store[i].name);
store[i].score=store[j].score;strcpy(store[i].number,store[j].number);strcpy(store[i].name,store[j].name);
store[j].score=mid;strcpy(store[j].number,str1);strcpy(store[j].name,str2);
}
}
fprintf(cfptr,"%s %s %f\n",store[i].number,store[i].name,store[i].score);
}
fclose(cfptr);fclose(fp);
}
int input(struct LOG *p){
printf("Input Number:");scanf("%s",p->number);
if(strcmp(p->number,"-1")==0)return -1;
else{
printf("Input Name:");scanf("%s",p->name);
printf("Input score:");scanf("%f",&p->score);
}
return 0;
}
FILE *openfile(char *name,char *openmode){
FILE *fp;
if((fp=fopen(name,openmode))==NULL){
printf("Can not open the file!\n");
exit(0);
}
return fp;
}
#include <stdio.h>
#include <stdlib.h>
int isprime(int n);
int main(){
FILE *fp;
if((fp=fopen("file_date.txt","w"))==NULL){
printf("Can not open the file!\n");
exit(0);
}
int i,count=0;
for(i=1;i<10000;i++){
if(isprime(i)!=-1){
count++;
if(count%10!=0)fprintf(fp,"%d\t",i);
else fprintf(fp,"%d\n",i);
}
}
int n;
fp=fopen("file_date.txt","rb");
while(!feof(fp)){
fscanf(fp,"%d\t",&n);
printf("%d\n",n);
}
fclose(fp);
return 0;
}
int isprime(int n){
int i,ret=-1;
if(n==1)return -1;
if(n==2||n==3)return 1;
for(i=2;i<=n/2;i++){
if(n%i==0)return ret;
}
return 1;
}
这是最后的,拷过来纯属无聊
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct LOG)
int N=0;//文件里有多少有效数据条
int count=0;//判断是否是第一次从文件中载入数据
typedef struct LOG{
char number[50];
char name[20];
float score;
char department[20];
struct LOG *next;
} DATE;
struct Order{
int soilder;
int ret;
};
int inputchoice(void);
int CountN(FILE *cfptr);
FILE *openfile(char *OpenMode);
struct LOG *AddLog(struct LOG *head,FILE *cfptr);
struct LOG *InputLog(struct LOG *p);
struct LOG *LoadFile(struct LOG **head,FILE *cfptr,struct LOG **p1);//二级指针,在函数内改变指针指向
struct LOG *ListLog(struct LOG *head,FILE *cfptr);
struct LOG *ListOppointedLog(struct LOG *head,FILE *cfptr);
struct LOG *DeleteLog(struct LOG *head,FILE *cfptr);
struct LOG *ListOrder(struct LOG *head,FILE *cfptr);
int main(){
int n=2;
FILE *fp=openfile("r+");
struct LOG *head=NULL;
N=CountN(fp);
printf("%d\n",N);
while(n!=0){
n=inputchoice();
switch (n)
{
case 1:
fp=openfile("a+");
head=AddLog(head,fp);
break;
case 2:
fp=openfile("r");
head=ListLog(head,fp);
break;
case 3:
fp=openfile("r");
head=ListOppointedLog(head,fp);
break;
case 4:
fp=openfile("r+");
head=DeleteLog(head,fp);
break;
case 5:
fp=openfile("r+");
head=ListOrder(head,fp);
break;
default :printf("Input Error!\n");
}
}
fclose(fp);
return 0;
}
int inputchoice(){
int n;
printf("1-Add new log\n");
printf("2-List all log\n");
printf("3-List oppointed log\n");
printf("4-Delete log\n");
printf("5-List logs in order\n");
printf("0-exit program!\n");
scanf("%d",&n);
return n;
}
int CountN(FILE *cfptr){
long n=0;
fseek(cfptr,0,2);
n=(ftell(cfptr))/44;
return n;
}
FILE *openfile(char *OpenMode){
FILE *cfptr;
if((cfptr=fopen("log.txt",OpenMode))==NULL){
printf("Can not open the file!\n");
exit(0);
}
return cfptr;
}
struct LOG *LoadFile(struct LOG **head,FILE *cfptr,struct LOG **p2){
int n=0;
DATE *p,*p1;
p1=p=(struct LOG*)malloc(LEN);
rewind(cfptr);
while(n<N){
fscanf(cfptr,"%s%s%f%s\n",p->number,p->name,&p->score,p->department);
//printf("%s %s %f\n",p->number,p->name,p->score);
if(n==0)*head=p;
else p1->next=p;
p1=p;
p=(struct LOG*)malloc(LEN);
n++;
}
p1->next=NULL;free(p);
*p2=p1;
// p=head;
// while(p!=NULL){
// printf("%s %s %f\n",p->number,p->name,p->score);
// p=p->next;
// }
return *p2;
}
struct LOG *AddLog(DATE *head,FILE *cfptr){
DATE *p,*p1;
p1=head;
p=(struct LOG*)malloc(LEN);
p=InputLog(p);
//printf("\t%s\t%f\t",p->name,p->score);
if(N==0){
// rewind(cfptr);
// fprintf(cfptr,"Number Name Score Department\n");
head=p;
p->next=NULL;
}
else{
if(count==0){
p1=LoadFile(&head,cfptr,&p1);
count++;
}
p1->next=p;
p->next=NULL;
}
// if(count>1){
// tail->next=p;
// tail=p;
// tail->next=NULL;
// }
fseek(cfptr,0,2);
fprintf(cfptr,"%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
N++;
return head;
}
struct LOG *ListLog(struct LOG *head,FILE *cfptr){
DATE *p;
if(count==0){
p=LoadFile(&head,cfptr,&p);
count++;
}
p=head;
int ret=0;
while(p!=NULL){
if(ret==0){
printf("\nNumber Name Score Department\n");
ret++;
}
printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
p=p->next;
}
if(ret==0)printf("There is no log or something wrong!\n");
return head;
}
struct LOG *ListOppointedLog(struct LOG *head,FILE *cfptr){
DATE *p;
if(count==0){
p=LoadFile(&head,cfptr,&p);
count++;
}
p=head;
char godmind[20];
int ret=0,ret1=0;
printf("please input the name,major or number you want to enquiry\n");
scanf("%s",godmind);
if('0'<=godmind[0]&&godmind[0]<='9'){
while(p!=NULL){
if(strcmp(godmind,p->number)==0){
printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
ret++;
}
p=p->next;
}
}
else {
while(p!=NULL){
if(strcmp(godmind,p->name)==0){
printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
ret++;
}
p=p->next;
if(ret>1||ret==0)continue;
ret1++;
}
}
if(ret1==0&&ret==0){
p=head;
while(p!=NULL){
if(strcmp(godmind,p->department)==0){
printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
ret1++;
}
p=p->next;
}
}
if(ret==0&&ret1==0)printf("Not Found!\n");
return head;
}
struct LOG *DeleteLog(struct LOG *head,FILE *cfptr){
DATE *p,*p1;
int n=0;
char godmind[20];
printf("Please input the meseage you want to delete(name or number):\n");
scanf("%s",godmind);
if(count==0){
p=LoadFile(&head,cfptr,&p);
count++;
}
p1=p=head;
if('0'<=godmind[0]&&godmind[0]<='9'){
while(strcmp(godmind,p->number)!=0&&p->next!=NULL){
p1=p;
p=p->next;
}
if(strcmp(godmind,p->number)==0){
if(p==head)head=p->next;
else p1->next=p->next;
free(p);
printf("Delete:%s\n",godmind);
N--;
}
else printf("The list is NULL!\n");
}
else {
while(strcmp(godmind,p->name)!=0&&p->next!=NULL){
p1=p;
p=p->next;
}
if(strcmp(godmind,p->name)==0){
if(p==head)head=p->next;
else p1->next=p->next;
free(p);
printf("Delete %s message!\n",godmind);
N--;
}
else printf("The list is NULL!\n");
}
p=head;
cfptr=openfile("w");
while(p!=NULL){
fprintf(cfptr,"%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
p=p->next;
}
return head;
}
struct LOG *ListOrder(struct LOG *head,FILE *cfptr){
DATE *p,*p1;
int i;
struct Order *order;
order=(struct Order *)calloc(N,sizeof(struct Order));
for(i=0;i<N;i++){
order[i].soilder=i;
order[i].ret=0;
}
int choice;
if(count==0){
p=LoadFile(&head,cfptr,&p);
count++;
}
p1=p=head;
printf("1-List by score\n2-List by number\n");
scanf("%d",&choice);
switch(choice){
case 1:
{
float max=-1;
int i=0,j;
while(p!=NULL){
max=-1;p1=head;j=0;
while(p1!=NULL){
if(order[j].ret==0&&p1->score>max){
max=p1->score;
order[i].soilder=j;
}
j++;
p1=p1->next;
}
order[order[i].soilder].ret=1;
i++;
p=p->next;
}
for(i=0;i<N;i++){
p=head;
for(j=0;j<order[i].soilder;j++)p=p->next;
printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
}
break;
}
case 2:
break;
default:printf("Input Error!\n");
}
return head;
}
struct LOG *InputLog(struct LOG *p){
printf("Enter the number:");scanf("%s",p->number);
printf("Enter the name:");scanf("%s",p->name);
printf("Enter the score:");scanf("%f",&p->score);
printf("Enter the department:");scanf("%s",p->department);
printf("Input Finished!\n\n");
return p;
}