C语言进阶1:文件 *** 作

C语言进阶1:文件 *** 作,第1张

C语言进阶1:文件 *** 作

C语言进阶1:文件 *** 作
  • 1、文件输入和 *** 作
    • 1.1 Hello.c
    • 1.2 编译
    • 1.3 执行
  • 2、文件打开关闭:fopen()和fclose()
    • 2.1 打开文件:fopen()
      • 2.1.1 函数原型
      • 2.1.2 参数
      • 2.1.3 打开的基本方式
      • 2.1.4 打开组合方式
      • 2.1.5 返回值
    • 2.2 关闭文件:fclose()
      • 2.2.1 函数原型
      • 2.2.2 参数和返回值
    • 2.3 基本框架
  • 3、文本读写:fprintf()和fscanf()
    • 3.1 函数原型
    • 3.2 举例
      • (1)将数据写入文件
      • (2)从文件中读出数据
      • (3)给文件写和从文件读
      • (4)结构体的 *** 作
      • (5)结构体的 *** 作,文件形式
      • (6)结构体 *** 作,不用终端给n的情况
      • (7)文件形式的 *** 作--switch互动界面
      • (8)结构体的 *** 作--文件和函数指针数组来 *** 作
  • 4、二进制读写:fread()和fwrite()
    • 4.1 函数原型
    • 4.2 参数
    • 4.3 返回值
    • 4.4 举例和练习
      • (1)将字符串写入文件
      • (2)从文件读出字符串
    • 4.5 文本vs二进制
    • 4.6 说明
    • 4.7 练习
  • 5、文件定位:ftell()和fseek()
    • 5.1 函数原型
    • 5.2 参数
    • 5.3 返回值
    • 5.4 示例
    • 5.5 练习-获取文件大小
    • 5.6 利用fseek和ftell优化前面的练习
  • 6、文件结尾判断feof()
  • 7、返回开头rewind()
    • 7.1 函数原型
    • 7.2 参数
    • 7.3 举例
  • 8、清空数据流fflush()
    • 8.1 函数原型
    • 8.2 参数
    • 8.3 举例
  • 9、 文件重命名rename()和文件删除remove()
    • 9.1 函数原型
  • 10、实践

1、文件输入和 *** 作

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

1.1 Hello.c
char name[256];
scanf("%s",name);
printf("Hello %sn",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 
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 
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 %sn", i, f, c, str);
}
(2)从文件中读出数据
#include 
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 %sn", &i, &f, &c, str);
	printf("%d %f %c %sn",i,f,c,str);
}
(3)给文件写和从文件读
#include 

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

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

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

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

}

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

(4)结构体的 *** 作
#include 
#include 

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 
(5)结构体的 *** 作,文件形式 
#include 
#include 

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 
(6)结构体 *** 作,不用终端给n的情况 
#include 
#include

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 
(7)文件形式的 *** 作–switch互动界面 
#include 
#include
#include 
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 
(8)结构体的 *** 作–文件和函数指针数组来 *** 作 
#include 
#include
#include 
#include 


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;iscores > ((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=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 
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 
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 
#include 

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 
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 
#include 
int main(int agrc,char *argv[]){
    FILE* fp = fopen(argv[1],"r");
    if(fp){
          fseek(fp,0,2);
          long size = ftell(fp);
          printf("%s大小为%ldBn",argv[1],size);
    }
}
5.6 利用fseek和ftell优化前面的练习
#include 
#include
#include 
#include 


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;iscores > ((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=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 
#include 

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;iname)==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 usern");
		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 %sn",info.name);
			break;
		}
		}
	}
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5699159.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存