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. | 打开方式 | 含义 |
---|
1 | r(read) | 读 | 2 | w(write) | 写 | 3 | a(append) | 追加 | 4 | +(plus) | 读或者写,主要是配合r、w、a使用 | 5 | t(txt) | 文本文件(默认) | 6 | b(binary) | 二进制文件 |
2.1.4 打开组合方式
No. | 打开方式 | 含义 |
---|
1 | r | 以只读的方式打开文件,前提是这个文件必须存在(只写 r 默认是文本文件) | 2 | r+ | 以可读可写的方式打开文件,前提是这个文件必须存在(默认是文本文件) | 3 | rb | 以只读的方式打开一个二进制文件,前提是这个文件必须存在。 | 4 | rb+ | 以可读可写的方式打开一个二进制文件,前提是这个文件必须存在。 | 5 | w | 以只写的方式打开文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容。 | 6 | w+ | 以可读可写的方式打开文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容。 | 7 | wb | 以只写的方式打开一个二进制文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容。 | 8 | wb+ | 以可读可写的方式打开一个二进制文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容。 | 9 | a | 以追加的方式打开只写文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容。 | 10 | a+ | 以追加的方式打开一个可读可写的文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容。 | 11 | ab | 以追加的方式打开一个二进制只写文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容。 | 12 | ab+ | 以追加的方式打开一个二进制可读可写文件,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容。 |
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){
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];
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);
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){
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. | 参数 | 作用 |
---|
1 | ptr | 一个指针,在fread()中是从文件里读入的数据存放的地址;在fwrite()中是写入到文件里的数据存放 的地址。 | 2 | size | 每次要读写的字节数 | 3 | count | 读写的次数 | 4 | stream | 文件指针 |
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. | 参数 | 含义 |
---|
1 | stream | 文件指针 | 2 | offset | 偏移量,基于起始点偏移了offset个字节 | 3 | whence | 起始点 |
No. | whence | 数值 | 含义 |
---|
1 | SEEK_SET | 0 | 从头开始 | 2 | SEEK_CUR | 1 | 从当前开始 | 3 | SEEK_END | 2 | 从结束开始 |
5.3 返回值
ftell()返回文件指针当前位置,基于文件开头的偏移字节数。
5.4 示例
fseek(stream, 0, SEEK_END);
fseek(stream, -10, SEEK_CUR);
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);
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;
}
}
}
}
|