c语言文件操作函数

1. 按照字符读写文件:fgetc(),fputc()

2. 按照行读写文件:fputs(), fgets()

3. 按照块读写文件:fread(), fwirte()

4. 按照格式化读写文件:fprintf(),fscanf()

5. 按照随机位置读写文件:fseek(), ftell(), rewind()    

1. 字符读写函数

int fputc(int ch, FILE * stream);
功能:将ch转换为unsigned char后写入stream指定的文件中
参数:
	ch:需要写入文件的字符
	stream:文件指针
返回值:
	成功:成功写入文件的字符
	失败:返回-1

int fgetc(FILE * stream);
功能:从stream指定的文件中读取一个字符
参数:
	stream:文件指针
返回值:
	成功:返回读取到的字符
	失败:-1

int feof(FILE * stream);
功能:检测是否读取到了文件结尾
参数:
	stream:文件指针
返回值:
	非0值:已经到文件结尾
	0:没有到文件结尾
案例:
void test(){

	//写文件
	FILE* fp_write= NULL;
	//写方式打开文件
	fp_write = fopen("./mydata.txt", "w+");
	if (fp_write == NULL){
		return;
	}

	char buf[] = "this is a test for pfutc!";
	for (int i = 0; i < strlen(buf);i++){
		fputc(buf[i], fp_write);
	}
	
	fclose(fp_write);

	//读文件
	FILE* fp_read = NULL;
	fp_read = fopen("./mydata.txt", "r");
	if (fp_read == NULL){
		return;
	}

#if 0
	//判断文件结尾 注意:多输出一个空格
	while (!feof(fp_read)){
		printf("%c",fgetc(fp_read));
	}
#else
	char ch;
	while ((ch = fgetc(fp_read)) != EOF){
		printf("%c", ch);
	}
#endif
}

将把流指针fp指向的文件中的一个字符读出,并赋给ch,当执行fgetc()函数时,若当时文件指针指到文件尾,即遇到文件结束标志EOF(其对应值为-1),该函数返回一个-1 给ch,在程序中常用检查该函数返回值是否为 -1 来判断是否已读到文件尾,从而决定是否继续。

2. 行读写函数

int fputs(const char * str, FILE * stream);
功能:将str所指定的字符串写入到stream指定的文件中, 字符串结束符 '\0'  不写入文件。 
参数:
	str:字符串
	stream:文件指针
返回值:
	成功:0
	失败:-1

char * fgets(char * str, int size, FILE * stream);
功能:从stream指定的文件内读入字符,保存到str所指定的内存空间,直到出现换行字符、读到文件结尾或是已读了size - 1个字符为止,最后会自动加上字符 '\0' 作为字符串结束。
参数:
	str:字符串
	size:指定最大读取字符串的长度(size - 1)
	stream:文件指针
返回值:
	成功:成功读取的字符串
	读到文件尾或出错: NULL
案例:
void test(){

	//写文件
	FILE* fp_write= NULL;
	//写方式打开文件
	fp_write = fopen("./mydata.txt", "w+");
	if (fp_write == NULL){
		perror("fopen:");
		return;
	}

	char* buf[] = {
		"01 this is a test for pfutc!\n",
		"02 this is a test for pfutc!\n",
		"03 this is a test for pfutc!\n",
		"04 this is a test for pfutc!\n",
	};
	for (int i = 0; i < 4; i ++){
		fputs(buf[i], fp_write);
	}
	
	fclose(fp_write);

	//读文件
	FILE* fp_read = NULL;
	fp_read = fopen("./mydata.txt", "r");
	if (fp_read == NULL){
		perror("fopen:");
		return;
	}

	//判断文件结尾
	while (!feof(fp_read)){
		char temp[1024] = { 0 };
		fgets(temp, 1024, fp_read);
		printf("%s",temp);
	}

	fclose(fp_read);
}

3. 块读写函数

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:以数据块的方式给文件写入内容
参数:
	ptr:准备写入文件数据的地址
	size: size_t 为 unsigned int类型,此参数指定写入文件内容的块数据大小
	nmemb:写入文件的块数,写入文件数据总大小为:size * nmemb
	stream:已经打开的文件指针
返回值:
	成功:实际成功写入文件数据的块数,此值和nmemb相等
	失败:0

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:以数据块的方式从文件中读取内容
参数:
	ptr:存放读取出来数据的内存空间
	size: size_t 为 unsigned int类型,此参数指定读取文件内容的块数据大小
	nmemb:读取文件的块数,读取文件数据总大小为:size * nmemb
	stream:已经打开的文件指针
返回值:
	成功:实际成功读取到内容的块数,如果此值比nmemb小,但大于0,说明读到文件的结尾。
	失败:0
案例:
typedef struct _TEACHER{
	char name[64];
	int age;
}Teacher;

void test(){

	//写文件
	FILE* fp_write= NULL;
	//写方式打开文件
	fp_write = fopen("./mydata.txt", "wb");
	if (fp_write == NULL){
		perror("fopen:");
		return;
	}

	Teacher teachers[4] = {
		{ "Obama", 33 },
		{ "John", 28 },
		{ "Edward", 45},
		{ "Smith", 35}
	};
	
	for (int i = 0; i < 4; i ++){
		fwrite(&teachers[i],sizeof(Teacher),1, fp_write);
	}
	//关闭文件
	fclose(fp_write);

	//读文件
	FILE* fp_read = NULL;
	fp_read = fopen("./mydata.txt", "rb");
	if (fp_read == NULL){
		perror("fopen:");
		return;
	}

	Teacher temps[4];
	fread(&temps, sizeof(Teacher), 4, fp_read);
	for (int i = 0; i < 4;i++){
		printf("Name:%s Age:%d\n",temps[i].name,temps[i].age);
	}

	fclose(fp_read);
}

4. 格式化读写函数

int fprintf(FILE * stream, const char * format, ...);
功能:根据参数format字符串来转换并格式化数据,然后将结果输出到stream指定的文件中,指定出现字符串结束符 '\0'  为止。
参数:
	stream:已经打开的文件
	format:字符串格式,用法和printf()一样
返回值:
	成功:实际写入文件的字符个数
	失败:-1

int fscanf(FILE * stream, const char * format, ...);
功能:从stream指定的文件读取字符串,并根据参数format字符串来转换并格式化数据。
参数:
	stream:已经打开的文件
	format:字符串格式,用法和scanf()一样
返回值:
	成功:实际从文件中读取的字符个数
	失败: - 1

注意fscanf遇到空格和换行时结束。

案例:
void test(){

	//写文件
	FILE* fp_write= NULL;
	//写方式打开文件
	fp_write = fopen("./mydata.txt", "w");
	if (fp_write == NULL){
		perror("fopen:");
		return;
	}

	fprintf(fp_write,"hello world:%d!",10);

	//关闭文件
	fclose(fp_write);

	//读文件
	FILE* fp_read = NULL;
	fp_read = fopen("./mydata.txt", "rb");
	if (fp_read == NULL){
		perror("fopen:");
		return;
	}
	
	char temps[1024] = { 0 };
	while (!feof(fp_read)){
		fscanf(fp_read, "%s", temps);
		printf("%s", temps);
	}

	fclose(fp_read);
}

5. 随机读写函数

int fseek(FILE *stream, long offset, int whence);
功能:移动文件流(文件光标)的读写位置。
参数:
	stream:已经打开的文件指针
	offset:根据whence来移动的位移数(偏移量),可以是正数,也可以负数,如果正数,则相对于whence往右移动,如果是负数,则相对于whence往左移动。如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了 文件末尾,再次写入时将增大文件尺寸。
	whence:其取值如下:
		SEEK_SET:从文件开头移动offset个字节
		SEEK_CUR:从当前位置移动offset个字节
		SEEK_END:从文件末尾移动offset个字节
返回值:
	成功:0
	失败:-1

long ftell(FILE *stream);
功能:获取文件流(文件光标)的读写位置。
参数:
	stream:已经打开的文件指针
返回值:
	成功:当前文件流(文件光标)的读写位置
	失败:-1

void rewind(FILE *stream);
功能:把文件流(文件光标)的读写位置移动到文件开头。
参数:
	stream:已经打开的文件指针
返回值:
	无返回值
案例:
typedef struct _TEACHER{
	char name[64];
	int age;
}Teacher;

void test(){
	//写文件
	FILE* fp_write = NULL;
	//写方式打开文件
	fp_write = fopen("./mydata.txt", "wb");
	if (fp_write == NULL){
		perror("fopen:");
		return;
	}

	Teacher teachers[4] = {
		{ "Obama", 33 },
		{ "John", 28 },
		{ "Edward", 45 },
		{ "Smith", 35 }
	};

	for (int i = 0; i < 4; i++){
		fwrite(&teachers[i], sizeof(Teacher), 1, fp_write);
	}
	//关闭文件
	fclose(fp_write);

	//读文件
	FILE* fp_read = NULL;
	fp_read = fopen("./mydata.txt", "rb");
	if (fp_read == NULL){
		perror("fopen:");
		return;
	}

	Teacher temp;
	//读取第三个数组
	fseek(fp_read , sizeof(Teacher) * 2 , SEEK_SET);
	fread(&temp, sizeof(Teacher), 1, fp_read);
	printf("Name:%s Age:%d\n",temp.name,temp.age);

	memset(&temp,0,sizeof(Teacher));

	fseek(fp_read, -(int)sizeof(Teacher), SEEK_END);
	fread(&temp, sizeof(Teacher), 1, fp_read);
	printf("Name:%s Age:%d\n", temp.name, temp.age);

	rewind(fp_read);
	fread(&temp, sizeof(Teacher), 1, fp_read);
	printf("Name:%s Age:%d\n", temp.name, temp.age);

	fclose(fp_read);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值