栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言进阶1:文件操作

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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;
		}
		}
	}
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/699033.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号