IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言进阶1:文件操作 -> 正文阅读

[C++知识库]C语言进阶1:文件操作

作者:recommend-item-box type_blog clearfix

1、文件输入和操作

使用printf()和命令行重定向>实现文件输出;使用scanf()和命令行重定向<实现文件输入。

1.1 Hello.c

char name[256];
scanf("%s",name);
printf("Hello %s\n",name);

1.2 编译

gcc Hello.c -o Hello

1.3 执行

Hello > Hi.txt
Hello < Hi.txt
Hello < Hi.txt > Hello.txt

2、文件打开关闭:fopen()和fclose()

2.1 打开文件:fopen()

2.1.1 函数原型

#include <stdio.h>
FILE *fopen(char restrict *filename, char restrict *mode);

2.1.2 参数

参数作用
filename需要打开的文件
mode文件打开方式

2.1.3 打开的基本方式

No.打开方式含义
1r(read)
2w(write)
3a(append)追加
4+(plus)读或者写,主要是配合r、w、a使用
5t(txt)文本文件(默认)
6b(binary)二进制文件

2.1.4 打开组合方式

No.打开方式含义
1r以只读的方式打开文件,前提是这个文件必须存在(只写 r 默认是文本文件)
2r+以可读可写的方式打开文件,前提是这个文件必须存在(默认是文本文件)
3rb以只读的方式打开一个二进制文件,前提是这个文件必须存在。
4rb+以可读可写的方式打开一个二进制文件,前提是这个文件必须存在。
5w以只写的方式打开文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容。
6w+以可读可写的方式打开文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容。
7wb以只写的方式打开一个二进制文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容。
8wb+以可读可写的方式打开一个二进制文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容。
9a以追加的方式打开只写文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容。
10a+以追加的方式打开一个可读可写的文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容。
11ab以追加的方式打开一个二进制只写文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容。
12ab+以追加的方式打开一个二进制可读可写文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容。

a只能追加不能修改,w会把文件清空,r+读写方式可以修改文件原有内容。

2.1.5 返回值

如果文件顺利打开,则返回值是指向这个文件流的文件指针,如果文件打开失败,返回NULL。

2.2 关闭文件:fclose()

2.2.1 函数原型

int flcose(FILE* stream);

2.2.2 参数和返回值

stream文件指针

2.3 基本框架

一般来说,文件打开失败会做一个文件指针错误判断

FILE *fp = fopen("文件路径", "打开方式");
if(NULL != fp){//判断为真,就是打开成功
    //code 
    fclose(fp);
}

3、文本读写:fprintf()和fscanf()

3.1 函数原型

int fprintf(FILE *stream, char *format, argument...);
int fscanf(FILE *stream, char *format, argument... );

fprintf()/fscanf()与printf()/scanf()使用非常相似,区别在于fprintf()/fscanf()第一个参数stream是文件描述符。

3.2 举例

(1)将数据写入文件

#include <stdio.h>
int main(){
	FILE *fp=fopen("/root/Desktop/fprintf.txt","w+");
	int i = 10;
	float f = 3.14;
	char c = 'C';
	char str[10] = "haha";
	fprintf(fp, "%d %f %c %s\n", i, f, c, str);
}

(2)从文件中读出数据

#include <stdio.h>
int main(){
	FILE *fp=fopen("/root/Desktop/fprintf.txt","w+");
	int i = 10;
	float f = 3.14;
	char c = 'C';
	char str[10] = "haha";
	fscanf(fp, "%d %f %c %s\n", &i, &f, &c, str);
	printf("%d %f %c %s\n",i,f,c,str);
}

(3)给文件写和从文件读

#include <stdio.h>

int main(int argc,char *argv[]){
    char s[40];

    //文件读取写到s里面
    FILE *pfile=fopen(argv[1],"r");
    if(NULL==pfile){
        printf("open file %s error\n",argv[1]);
	return 1;
    }
    fscanf(pfile,"%s",&s);
    fclose(pfile);
    pfile=NULL;
    printf("%s\n",s);

    //用fgets能忽略空格,但是不能超过s的长度
    FILE *pfile = fopen(argv[1],"r");
    if(NULL==pfile){
        printf("open file %s error\n",argv[1]);
	return 1;
    }
    fgets(s,sizeof(s),pfile);
    fclose(pfile);
    pfile=NULL;
    printf("%s\n",s);

	//给文件中写
    FILE *pfile = fopen(argv[1],"w");
    if(NULL==pfile){
        printf("open file %s error\n",argv[1]);
	return 1;
    }
    scanf("%s",&s);
    fprintf(pfile,"%s\n",s);
    fclose(pfile);
    pfile=NULL;

}

运行时:给./a.out 后面加上文件名

(4)结构体的操作

#include <stdio.h>
#include <stdbool.h>

typedef struct Student{
    char name[30];
    int age;
    bool male;
    float scores;
}Student,*PStudent;

//结构体的输出函数
void students_print(PStudent students,size_t n){
    for(int i=0;i<n;i++){
        printf("%s  %d  %d  %f \n",students[i].name,students[i].age,students[i].male,students[i].scores);
    }
}

//结构体输入函数
PStudent student_scanf(PStudent students,size_t n){
    for(int i=0;i<n;i++){
        scanf("%s",students[i].name);
        scanf("%d",&students[i].age);
        scanf("%d",&students[i].male);
        scanf("%f",&students[i].scores);
    }
    return students;
}

//主函数
int main(){
    int n;
    scanf("%d",&n);
    Student students[n];
    student_scanf(students,n);
    students_print(students,n);
}

(5)结构体的操作,文件形式

#include <stdio.h>
#include <stdbool.h>

typedef struct Student{
    char name[30];
    int age;
    bool male;
    float scores;
}Student,*PStudent;

//结构体的输出函数
void students_print(PStudent students,size_t n){
    for(int i=0;i<n;i++){
        printf("%s  %d  %d  %f \n",students[i].name,students[i].age,students[i].male,students[i].scores);
    }
}
//保存到文件中
void studengs_save(const char *file,const PStudent students,size_t n){
    FILE *pfile=fopen(file,"w");
    if(NULL == pfile){
        printf("file %s open error!\n",file);
	return;
    }
    for(int i=0;i<n;i++){
        fprintf(pfile,"%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);
    }
    fclose(pfile);
    pfile=NULL;
}
//从文件读入
PStudent students_load(const char *file,PStudent students,size_t n){ 
    FILE *pfile=fopen(file,"r");
    if(NULL == pfile){
        printf("file %s open error!\n",file);
	return students;
    }
    for(int i=0;i<n;i++){
        int res=
	fscanf(pfile,"%s%d%d%f\n",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
	if(EOF==res) break;
    }
    fclose(pfile);
    pfile=NULL;
    return students;
}



PStudent students_scanf(PStudent students,size_t n){
    for(int i=0;i<n;i++){  
	fscanf(stdin,"%s%d%d%f\n",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
    }
    return students;
}

int main(int argc,char *argv[]){
    int n;
    scanf("%d",&n);
    Student students[n];
    students_scanf(students,n);
    students_print(students,n);
    studengs_save(argv[1],students,n);
    students_load(argv[1],students,n);
    students_print(students,n);
}

(6)结构体操作,不用终端给n的情况

#include <stdio.h>
#include<stdbool.h>

typedef struct Student{
    char name[30];
    int age;
    bool male;
    float scores;

}Student,*PStudent;


void students_print(PStudent students,size_t n){
    for(int i=0;i<n;i++){
        printf("%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);

    }
}

void students_save(const char *file,const PStudent students,size_t n){
    FILE *pfile = fopen(file,"w");
    if(NULL == pfile){
      printf("file %s open error!\n",file);
      return;
    }
    fprintf(pfile,"%d\n",n);
    for(int i=0;i<n;i++){
       fprintf(pfile,"%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);
    }
    fclose(pfile);
    pfile=NULL;
}
size_t students_size(const char*file){   //把文件的第一个数据放入n中,文件第一个数据我们写成学生个数
    FILE *pfile = fopen(file,"r");
    if(NULL == pfile){
      printf("file %s open error!\n",file);
      return 0;
    }
    int n;
    fscanf(pfile,"%d",&n);
    fclose(pfile);
    pfile=NULL;
    return n;
}

PStudent students_load(const char *file,PStudent students,size_t n){
    FILE *pfile =fopen(file,"r");
    if(NULL==pfile){
        printf("file %s open error!\n",file);
        return students;
    }
    int num;
    fscanf(pfile,"%d",&num);
    if(num<n){
        printf("WARRING:fact count of students is less:%d\n",num);
    }
    for(int i=0;i<n;i++){
        int res=fscanf(pfile,"%s%d%d%f",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
        if (EOF==res) break;
    }
    fclose(pfile);
    pfile=NULL;
    return students;

}
PStudent students_scanf(PStudent students,size_t n){
    for(int i=0;i<n;i++){
       fscanf(stdin,"%s%d%d%f",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
    }
    return students;
}

int main(int argc,char *argv[]){

  int n=students_size(argv[1]);
  Student students[n];
  students_load(argv[1],students,n);
  students_print(students,n);
  return 0;
}

(7)文件形式的操作–switch互动界面

#include <stdio.h>
#include<stdbool.h>
#include <string.h>
typedef struct Student{
    char name[30];
    int age;
    bool male;
    float scores;

}Student,*PStudent;


void students_print(PStudent students,size_t n){
    for(int i=0;i<n;i++){
        printf("%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);

    }
}

void students_save(const char *file,const PStudent students,size_t n){
    FILE *pfile = fopen(file,"w");
    if(NULL == pfile){
      printf("file %s open error!\n",file);
      return;
    }
    fprintf(pfile,"%d\n",n);
    for(int i=0;i<n;i++){
       fprintf(pfile,"%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);
    }
    fclose(pfile);
    pfile=NULL;
}
size_t students_size(const char*file){   //抓的文件里面的第一个数字
    FILE *pfile = fopen(file,"r");
    if(NULL == pfile){
      printf("file %s open error!\n",file);
      return 0;
    }
    int n;
    fscanf(pfile,"%d",&n);
    fclose(pfile);
    pfile=NULL;
    return n;
}

PStudent students_load(const char *file,PStudent students,size_t n){
    FILE *pfile =fopen(file,"r");
    if(NULL==pfile){
        printf("file %s open error!\n",file);
        return students;
    }
    int num;
    fscanf(pfile,"%d",&num);
    if(num<n){
        printf("WARRING:fact count of students is less:%d\n",num);
    }
    for(int i=0;i<n;i++){
        int res=fscanf(pfile,"%s%d%d%f",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
        if (EOF==res) break;
    }
    fclose(pfile);
    pfile=NULL;
    return students;

}
PStudent students_scanf(PStudent students,size_t n){
    for(int i=0;i<n;i++){
       fscanf(stdin,"%s%d%d%f",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
    }
    return students;
}
PStudent students_search(const char *name,PStudent students,size_t n){
    for(int i=0;i<n;i++){
        if(strcmp(name,students[i].name)==0){
            return students+i;
        }

    }
    return NULL;
}

int main(int argc,char *argv[]){
    char *menus[]={
    "NEW Student",
    "Show All Students",
    "Search Students",
    "Change Info",
    "Delete Info",
    "Sort by scores"
    };
    for(int i=0;i<sizeof(menus)/sizeof(menus[0]);i++){
        printf("%d. %s\n",i+1,menus[i]);
    }
    while(true){
        int count =students_size(argv[1]);
	Student students[count];
	students_load(argv[1],students,count);

	printf("Select option:");
	int option;
	scanf("%d",&option);
	switch(option){
	    case 1:{
		   Student s;
		   students_scanf(&s,1);
		   Student students2[count+1];
		   for(int i=0;i<count;i++){
		       students2[i]=students[i];

		   }
		   students2[count]=s;
		   students_save(argv[1],students2,count+1);
		   break;
		   }
	    case 2:{
		   if(0!=count){
		       students_print(students,count);
		   }else{
		       printf("No Students Info\n");
		   }
		   break;
		   }
   	    case 3:{
		   if(0!=count){
		       char name[30];
                       printf("Please input the name of student:");
		       scanf("%s",name);
		       students_load(argv[1],students,count);
		       PStudent s = students_search(name,students,count);
		       if(NULL==s){
		           printf("No Student %s\n",name);

		       }else{
		           students_print(s,1);
		       }
		   }else{
		        printf("No Students Info!\n");
		   }
		   break;
		   }
	     case 4:{
		   if(0!=count){
		       char name[30];
                       printf("Please input the name of student:");
		       scanf("%s",name);
		       students_load(argv[1],students,count);
		       PStudent s = students_search(name,students,count);
		       if(NULL==s){
		           printf("No Student %s\n",name);

		       }else{
		           students_print(s,1);
			   printf("Input New Info:");
			   students_scanf(s,1);
			   students_save(argv[1],students,count);
		       }
		    
		    }else{
		        printf("NO Students Info\n");
		    }
		    break;
	}
	     case 5:{
             if(0!= count){
                char name[30];
                printf("Please input the name of student:");
                scanf("%s",name);
                PStudent s = students_search(name,students,count);
                if(NULL==s){
                   printf("No student %s\n",name);
                }else{
                   students_print(s,1);
                   *s = students[count-1];
                   students_save(argv[1],students,count-1);
                }
             }else{
                printf("No Students Info\n");
             }
             break;
             }
	     case 6:{
		        if(0!=count){
			    qsort(students,count,sizeof(Student),students_scores_down);
			}else{
			    printf("No Students Info!\n");
			}
		    }
		    break;
	      default:
		    printf("Error:%d option is not exist!\n",option);
    }
    }
 }

(8)结构体的操作–文件和函数指针数组来操作

#include <stdio.h>
#include<stdbool.h>
#include <string.h>
#include <stdlib.h>


char *filename;
typedef struct Student{
    char name[30];
    int age;
    bool male;
    float scores;

}Student,*PStudent;


void students_print(PStudent students,size_t n){
    for(int i=0;i<n;i++){
        printf("%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);

    }
}

void students_save(const char *file,const PStudent students,size_t n){
    FILE *pfile = fopen(file,"w");
    if(NULL == pfile){
      printf("file %s open error!\n",file);
      return;
    }
    fprintf(pfile,"%d\n",n);
    for(int i=0;i<n;i++){
       fprintf(pfile,"%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);
    }
    fclose(pfile);
    pfile=NULL;
}
size_t students_size(const char*file){   //抓的文件里面的第一个数字
    FILE *pfile = fopen(file,"r");
    if(NULL == pfile){
      printf("file %s open error!\n",file);
      return 0;
    }
    int n;
    fscanf(pfile,"%d",&n);
    fclose(pfile);
    pfile=NULL;
    return n;
}

PStudent students_load(const char *file,PStudent students,size_t n){
    FILE *pfile =fopen(file,"r");
    if(NULL==pfile){
        printf("file %s open error!\n",file);
        return students;
    }
    int num;
    fscanf(pfile,"%d",&num);
    if(num<n){
        printf("WARRING:fact count of students is less:%d\n",num);
    }
    for(int i=0;i<n;i++){
        int res=fscanf(pfile,"%s%d%d%f",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
        if (EOF==res) break;
    }
    fclose(pfile);
    pfile=NULL;
    return students;

}
PStudent students_scanf(PStudent students,size_t n){
    for(int i=0;i<n;i++){
       fscanf(stdin,"%s%d%d%f",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
    }
    return students;
}
PStudent students_search(const char *name,PStudent students,size_t n){
    for(int i=0;i<n;i++){
        if(strcmp(name,students[i].name)==0){
            return students+i;
        }

    }
    return NULL;
}
int students_scores_up(const void *a,const void *b){
    return ((PStudent)a)->scores > ((PStudent)b)->scores?-1:1;
}
int students_scores_down(const void *a,const void *b){
    return ((PStudent)a)->scores < ((PStudent)b)->scores?-1:1;
}
void NewStudent(PStudent students,size_t count){

  	Student s;
	students_scanf(&s,1);
	Student students2[count+1];
	for(int i=0;i<count;i++){
	    students2[i]=students[i];

 	}
	students2[count]=s;
	students_save(filename,students2,count+1);

}

void ShowAllStudent(PStudent students,size_t count){

		   if(0!=count){
		       students_print(students,count);
		   }else{
		       printf("No Students Info\n");
		   }
}

void SearchStudent(PStudent students,size_t count){
    
		   if(0!=count){
		       char name[30];
                       printf("Please input the name of student:");
		       scanf("%s",name);
		       students_load(filename,students,count);
		       PStudent s = students_search(name,students,count);
		       if(NULL==s){
		           printf("No Student %s\n",name);

		       }else{
		           students_print(s,1);
		       }
		   }else{
		        printf("No Students Info!\n");
		   }
}
void EditStudent(PStudent students,size_t count){

		   if(0!=count){
		       char name[30];
                       printf("Please input the name of student:");
		       scanf("%s",name);
		       students_load(filename,students,count);
		       PStudent s = students_search(name,students,count);
		       if(NULL==s){
		           printf("No Student %s\n",name);

		       }else{
		           students_print(s,1);
			   printf("Input New Info:");
			   students_scanf(s,1);
			   students_save(filename,students,count);
		       }
		    
		    }else{
		        printf("NO Students Info\n");
		    }
}
void DeleteStudent(PStudent students,size_t count){
    
             if(0!= count){
                char name[30];
                printf("Please input the name of student:");
                scanf("%s",name);
                PStudent s = students_search(name,students,count);
                if(NULL==s){
                   printf("No student %s\n",name);
                }else{
                   students_print(s,1);
                   *s = students[count-1];
                   students_save(filename,students,count-1);
                }
             }else{
                printf("No Students Info\n");
             }
}
void SortStudents(PStudent students,size_t count){

		        if(0!=count){
			    qsort(students,count,sizeof(Student),students_scores_down);
			}else{
			    printf("No Students Info!\n");
			}
}

void Exit(PStudent students,size_t count){
    exit(0);
}

int main(int argc,char *argv[]){
    if(argc!=2){
        printf("Usag:%s  filename\n",argv[0]);
	return 1;
    }
    filename=argv[1];
    char *menus[]={
    "NEW Student",
    "Show All Students",
    "Search Students",
    "Change Info",
    "Delete Info",
    "Sort by scores"
    };
    for(int i=0;i<sizeof(menus)/sizeof(menus[0]);i++){
        printf("%d. %s\n",i+1,menus[i]);
    }
    typedef void  (*func_t)(PStudent,size_t);
    func_t funcs[]={Exit,NewStudent,ShowAllStudent,SearchStudent,EditStudent,DeleteStudent,SortStudents};
    while(true){
        int count =students_size(filename);
	Student students[count];
	students_load(argv[1],students,count);

	printf("Select option:");
	int option;
	scanf("%d",&option);
	if(option >=0 && option <=6){
	    funcs[option](students,count);
	}else{
	    printf("Error!");
	}
    }
 }

4、二进制读写:fread()和fwrite()

4.1 函数原型

size_t fread(void *ptr, size_t size, size_t count, FILE* stream);
size_t fwrite(void *ptr, size_t size, size_t count, FILE* stream);

4.2 参数

No.参数作用
1ptr一个指针,在fread()中是从文件里读入的数据存放的地址;在fwrite()中是写入到文件里的数据存放 的地址。
2size每次要读写的字节数
3count读写的次数
4stream文件指针

4.3 返回值

成功读取/写入的字节数

4.4 举例和练习

(1)将字符串写入文件

#include <stdio.h>
int main(int argc,char *argv[]){
    FILE *pfile=fopen(argv[1],"wb+");
    if(pfile != NULL){
        char str[]="Hello World";
        fwrite(str,sizeof(str),1,pfile);
    }
}

(2)从文件读出字符串

#include <stdio.h>
int main(int argc,char *argv[]){
    FILE *pfile=fopen(argv[1],"r");
    if(pfile != NULL){
		char str[100];   
		fread(str, sizeof(str), 1, pfile);
    }
}

4.5 文本vs二进制

比较文本二进制
优势便于人类读写,跨平台文件较小,机器读写比较快
劣势文件较大,机器读写慢不便于人类读写,不跨平台
配置Unix用文件Windows用注册表

4.6 说明

Unix喜欢用文本文件来做数据存储和程序配置。
windows喜欢用二进制文件。
数据量较多使用数据库
多媒体使用二进制
通常使用第三方库读写文件,很少直接读写二进制文件。

4.7 练习

#include <stdio.h>
#include <stdbool.h>

typedef struct Student{
        char name[30];
        int age;
        bool male;
        float scores;
}Student,*PStudent;

void students_print(PStudent students,size_t n){
    for(int i=0;i<n;i++){
        printf("%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);

    }
}
int main(int argc,char *argv[]){
    FILE *pfile=fopen(argv[1],"rb+");
    if(NULL ==pfile){
        printf("open file %s failure\n",argv[1]);
    }
    Student s;
    fread(&s,sizeof(s),1,pfile);
    students_print(&s,1);
    fclose(pfile);
    pfile=NULL;
}        

5、文件定位:ftell()和fseek()

5.1 函数原型

// 获取位置
long ftell(FILE* stream);
// 设置位置
int fseek(FILE* stream,long offset,int whence);

5.2 参数

No.参数含义
1stream文件指针
2offset偏移量,基于起始点偏移了offset个字节
3whence起始点
No.whence数值含义
1SEEK_SET0从头开始
2SEEK_CUR1从当前开始
3SEEK_END2从结束开始

5.3 返回值

ftell()返回文件指针当前位置,基于文件开头的偏移字节数。

5.4 示例

fseek(stream, 0, SEEK_END);
// 将文件指针指向文件结尾,并偏移了 0 个字节,也就是直接将文件指针指向文件结尾
fseek(stream, -10, SEEK_CUR);
// 将文件指针指向当前位置,并偏移了 -10 个字节,也就是将文件指针往前移动10个字节

5.5 练习-获取文件大小

#include <stdio.h>
#include <stdlib.h>
int main(int agrc,char *argv[]){
    FILE* fp = fopen(argv[1],"r");
    if(fp){
          fseek(fp,0,2);
          long size = ftell(fp);
          printf("%s大小为%ldB\n",argv[1],size);
    }
}

5.6 利用fseek和ftell优化前面的练习

#include <stdio.h>
#include<stdbool.h>
#include <string.h>
#include <stdlib.h>


char *filename;
typedef struct Student{
    char name[30];
    int age;
    bool male;
    float scores;

}Student,*PStudent;


void students_print(PStudent students,size_t n){
    for(int i=0;i<n;i++){
        printf("%s %d %d %f\n",students[i].name,students[i].age,students[i].male,students[i].scores);

    }
}

void students_save(const char *file,const PStudent students,size_t n){
    FILE *pfile = fopen(file,"w");
    if(NULL == pfile){
      printf("file %s open error!\n",file);
      return;
    }
    fwrite(students,sizeof(Student),n,pfile);
    fclose(pfile);
    pfile=NULL;
}
size_t students_size(const char*file){   //抓的文件里面的第一个数字
    FILE *pfile = fopen(file,"r");
    if(NULL == pfile){
      printf("file %s open error!\n",file);
      return 0;
    }
    fseek(pfile,0,SEEK_END);
    int n=ftell(pfile)/sizeof(Student);
    fclose(pfile);
    pfile=NULL;
    return n;
}

PStudent students_load(const char *file,PStudent students,size_t n){
    FILE *pfile =fopen(file,"r");
    if(NULL==pfile){
        printf("file %s open error!\n",file);
        return students;
    }
    fread(students,sizeof(Student),n,pfile);
    fclose(pfile);
    pfile=NULL;
    return students;

}
PStudent students_scanf(PStudent students,size_t n){
    for(int i=0;i<n;i++){
       fscanf(stdin,"%s%d%d%f",students[i].name,&students[i].age,&students[i].male,&students[i].scores);
    }
    return students;
}
PStudent students_search(const char *name,PStudent students,size_t n){
    for(int i=0;i<n;i++){
        if(strcmp(name,students[i].name)==0){
            return students+i;
        }

    }
    return NULL;
}
int students_scores_up(const void *a,const void *b){
    return ((PStudent)a)->scores > ((PStudent)b)->scores?-1:1;
}
int students_scores_down(const void *a,const void *b){
    return ((PStudent)a)->scores < ((PStudent)b)->scores?-1:1;
}
void NewStudent(PStudent students,size_t count){

  	Student s;
	students_scanf(&s,1);
	Student students2[count+1];
	for(int i=0;i<count;i++){
	    students2[i]=students[i];

 	}
	students2[count]=s;
	students_save(filename,students2,count+1);

}

void ShowAllStudent(PStudent students,size_t count){

		   if(0!=count){
		       students_print(students,count);
		   }else{
		       printf("No Students Info\n");
		   }
}

void SearchStudent(PStudent students,size_t count){
    
		   if(0!=count){
		       char name[30];
                       printf("Please input the name of student:");
		       scanf("%s",name);
		       students_load(filename,students,count);
		       PStudent s = students_search(name,students,count);
		       if(NULL==s){
		           printf("No Student %s\n",name);

		       }else{
		           students_print(s,1);
		       }
		   }else{
		        printf("No Students Info!\n");
		   }
}
void EditStudent(PStudent students,size_t count){

		   if(0!=count){
		       char name[30];
                       printf("Please input the name of student:");
		       scanf("%s",name);
		       students_load(filename,students,count);
		       PStudent s = students_search(name,students,count);
		       if(NULL==s){
		           printf("No Student %s\n",name);

		       }else{
		           students_print(s,1);
			   printf("Input New Info:");
			   students_scanf(s,1);
			   students_save(filename,students,count);
		       }
		    
		    }else{
		        printf("NO Students Info\n");
		    }
}
void DeleteStudent(PStudent students,size_t count){
    
             if(0!= count){
                char name[30];
                printf("Please input the name of student:");
                scanf("%s",name);
                PStudent s = students_search(name,students,count);
                if(NULL==s){
                   printf("No student %s\n",name);
                }else{
                   students_print(s,1);
                   *s = students[count-1];
                   students_save(filename,students,count-1);
                }
             }else{
                printf("No Students Info\n");
             }
}
void SortStudents(PStudent students,size_t count){

		        if(0!=count){
			    qsort(students,count,sizeof(Student),students_scores_down);
			}else{
			    printf("No Students Info!\n");
			}
}

void Exit(PStudent students,size_t count){
    exit(0);
}

int main(int argc,char *argv[]){
    if(argc!=2){
        printf("Usag:%s  filename\n",argv[0]);
	return 1;
    }
    filename=argv[1];
    char *menus[]={
    "NEW Student",
    "Show All Students",
    "Search Students",
    "Change Info",
    "Delete Info",
    "Sort by scores"
    };
    for(int i=0;i<sizeof(menus)/sizeof(menus[0]);i++){
        printf("%d. %s\n",i+1,menus[i]);
    }
    typedef void  (*func_t)(PStudent,size_t);
    func_t funcs[]={Exit,NewStudent,ShowAllStudent,SearchStudent,EditStudent,DeleteStudent,SortStudents};
    while(true){
        int count =students_size(filename);
	Student students[count];
	students_load(argv[1],students,count);

	printf("Select option:");
	int option;
	scanf("%d",&option);
	if(option >=0 && option <=6){
	    funcs[option](students,count);
	}else{
	    printf("Error!");
	}
    }
 }

6、文件结尾判断feof()

函数原型

int feof(FILE* stream);

参数
stream文件指针
返回值
一旦文件指针指向文件结尾,就返回一个真值;否则返回非真值。

7、返回开头rewind()

7.1 函数原型

void rewind(FILE* stream);

7.2 参数

stream文件指针

7.3 举例

FILE *fp = fopen("./text.txt", "r+");
fseek(fp, 0, SEEK_END);   // 将文件指针指向文件结尾
long len = ftell(fp);     // 获取文件指针位置,得到文件的大小(Byte)
rewind(fp);               // 将文件指针重新指向文件开头

8、清空数据流fflush()

8.1 函数原型

void fflush(FILE* stream);

8.2 参数

stream数据流

8.3 举例

fflush(fp);        // 清空文件流

9、 文件重命名rename()和文件删除remove()

9.1 函数原型

int rename(const char *old_filename, const char *new_filename);
int remove(char * filename);

10、实践

实现一个简单的注册登录系统miniLogin

(1) 支持注册用户名和密码,用户名和密码必须包含字母和数字。
(2) 登录时,密码输入错误超过3次,退出登录。

#include <stdio.h>
#include <string.h>

typedef struct Login{
	char name[32];
	char pass[7];	
}Login;

void login_save(const char * file,Login *info,size_t n){
	FILE *pfile=fopen(file,"w");
	if(NULL==pfile){
		printf("file %s is not existed!\n",file);
		return;
	}
	fwrite(info,sizeof(Login),n,pfile);
	fclose(pfile);
	pfile=NULL;
}

Login login_scan(){
	Login info;
	printf("input user name:");
	scanf("%s",info.name);
	printf("input password:");
	scanf("%s",info.pass);
	return info;
}
const  Login *login_search(const Login *infos,size_t n,const Login* info){
	for(int i=0;i<n;++i){
		if(strcmp(infos[i].name,info->name)==0
			&& strcmp(infos[i].pass,info->pass)==0){
			return infos+i;
		}
	}
	return NULL;

}
int main(){
	const char *login = "login";
	FILE *pfile = fopen(login,"r");
	if(NULL==pfile){
		printf("NO User,input the first user\n");
		Login info=login_scan();
		login_save(login,&info,1);
	}else{
		fseek(pfile,0,SEEK_END);
		int size =ftell(pfile);
		int n=size/sizeof(Login);
		Login infos[n];
		rewind(pfile);
		fread(infos,sizeof(Login),n,pfile);

		for(int i=0;i<3;i++){
		Login info=login_scan();
	       	const Login *res=login_search(infos,n,&info);
		if(NULL==res){
			printf("Error:user name or password inconrect!\n");
		}else{
			printf("Welcome %s\n",info.name);
			break;
		}
		}
	}
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-08 13:48:12  更:2022-01-08 13:50:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:47:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码