【笔记】C_文件操作

1.fopen与fclose

FILE *fopen(char *filename, char *mode);

fopen的函数如上,第一个参数文件名(路径),第二个参数为打开方式。
打开方式包括打开权限:r,w,a,r+,w+,a+六种,与读写方式t,b两种。
r:读,若不存在该文件,fopen返回NULL。
w:写,若不存在则新建,若存在删除新建。
a:追加,若不存在则新建,若存在写入内容追加在已存在文件后。
+:读写,前面加上r,w,a,则是以x方式打开文件,拥有读写权限。r+,若不存在该文件,则fopen返回NULL。w+,若不存在则新建,存在删除新建,拥有读写。
t:文本格式
b:二进制格式
tb不能书写格式不能在第一位:rb+,r+t。

int fclose(FILE *fp);

正常关闭返回0,关闭异常返回非0。

一个程序,打开demo文件,读取每一行数据:

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
#define N 100

int main(){
	FILE* fp;
	char buffer[N+1];
	if((fp=fopen("E:\\demo.txt","rt"))==NULL){
		puts("file open error!");
		exit(0);
	}
	while(fgets(buffer,N,fp)!=NULL){
		printf("%s",buffer);
	}
	if(fclose(fp)!=0){
		puts("file close error!");
		exit(0);
	}
	return 0;
}

2.fgetc与fputc(字符读写)

int fgetc (FILE *fp);
int fputc ( int ch, FILE *fp );

两个函数,成功都是返回读(写)的字符,失败返回EOF(宏定义)。
文件中有面向用户隐藏的指向标记,每fgetc一个字符,标记向下移动一个字符位置,读取结束,返回EOF。

int ferror(FILE* fp);
int feof(FILE* fp);

ferror函数用来判断文件读取是否出错,出错返回非0值,反之返回0。
feof函数用来判断文件标记是否读取岛结尾,指向末尾返回非0值,反之返回0。
读取demo的所有数据:

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)

int main(){
	FILE* fp;
	char ch;
	if((fp=fopen("E:\\demo.txt","rt+"))==NULL){
		puts("file open error!");
		exit(0);
	}
	while((ch=fgetc(fp))!=EOF){
		printf("%c",ch);
	}
	if(ferror(fp)!=0){
		puts("file get char error!");
		exit(0);
	}
	fclose(fp);
	return 0;
}

往demo中写入数据:

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)

int main(){
	FILE* fp;
	char ch;
	if((fp=fopen("E:\\demo.txt","a+t"))==NULL){
		puts("file open error!");
		exit(0);
	}
	while((ch=getchar())!='\n'){
		fputc(ch,fp);
	}
	fputc('\n', fp);
	fclose(fp);
	return 0;
}

3.fgets与fputs(字符串读写)

char *fgets ( char *str, int n, FILE *fp );
int fputs( char *str, FILE *fp );

读取字符串,不是读取一整行,而是读取n个字符的字符串。一共两点:1.fgets会自动补’\0’,所以char数组大小应该为n+1。2.fgets与gets不同的是,fgets自动识别换行符,而gets不会自动识别换行符。
写入字符串,写入成功返回非0值,失败返回EOF。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)
#define N 100

int main(){
	FILE* fp;
	char buffer[N+1];
	char putStr[102]={0};//在inpStr前添加换行符
	char inpStr[100]={0};//键盘输入
	if((fp=fopen("E:\\demo.txt","a+t"))==NULL){
		puts("file open error!");
		exit(0);
	}
	gets_s(inpStr);
	strcat(putStr,"\n");
	strcat(putStr,inpStr);
	if(fputs(putStr,fp)!=EOF){
		puts("put the str succeed!");
	}
	fclose(fp);
	if((fp=fopen("E:\\demo.txt","a+t"))==NULL){
		puts("file open error!");
		exit(0);
	}
	while(fgets(buffer,N,fp)!=NULL){
		printf("%s",buffer);
	}
	fclose(fp);
	return 0;
}

4.fread与fwrite(块读写)

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

两个返回的的都是count,若返回的count小于参数内的count,
fread可能表示读取错误,也可能读取到末尾。利用ferror与feof检测。
fwrite表示写入错误。

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
#define N 5

int main(){
	int a[N];
	int b[N];
	size_t size = sizeof(int);
	FILE* fp;
	if((fp=fopen("E:\\demo.txt","r+b"))==NULL){
		puts("file open error!");
		exit(0);
	}
	puts("please enter five nubmers:");
	for(int i=0;i<N;i++){
		scanf("%d",&a[i]);
	}
	if((fwrite(a,size,N,fp))!=N){
		puts("file write error!");
		exit(0);
	}
	rewind(fp);
	fread(b,size,N,fp);
	if(ferror(fp)!=0){
		puts("file read error!");
		exit(0);
	}
	for(int i=0;i<N;i++){
		printf("%d",b[i]);
	}
	fclose(fp);
	return 0;
}

块输入,读写方式需要采用b二进制方式打开文件,因为在windows下。
rewind函数表示把标记重置到指向数据第一位置。
使用块读写读写结构体:

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
#define N 2

struct stu {
	char name[10];
	int num;
	int age;
	int score;
}stuA[N], stuB[N], * ptrA, * ptrB;

int main() {
	ptrA = stuA;
	ptrB = stuB;
	size_t size = sizeof(struct stu);
	FILE* fp;
	if ((fp = fopen("E:\\demo", "w+b")) == NULL) {
		puts("file open error");
		exit(0);
	}
	puts("please enter two students' data:");
	for (int i = 0; i < N; i++, ptrA++) {
		scanf("%s %d %d %d", ptrA->name, &ptrA->num, &ptrA->age, &ptrA->score);
	}
	if ((fwrite(stuA, size, N, fp)) != N) {
		puts("file write error!");
		exit(0);
	}
	rewind(fp);
	fread(stuB, size, N, fp);
	if (ferror(fp) != 0) {
		puts("file read error!");
		exit(0);
	}
	for (int i = 0; i < N; i++, ptrB++) {
		printf("student:%s %d %d %d", ptrB->name, ptrB->num, ptrB->age, ptrB->score);
	}
	fclose(fp);
	return 0;
}

5.fscanf与fprintf(格式读写)

fscanf:从文件中以格式读出。
fprintf:以格式写入文件。

int fscanf ( FILE *fp, char * format, … );
int fprintf ( FILE *fp, char * format, … );

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
#define N 2
struct stu{
	char name[10];
	int num;
	int age;
	float score;
}stuA[N],stuB[N],*ptrA,*ptrB;
int main(){
	ptrA = stuA;
	ptrB = stuB;
	FILE* fp;
	if((fp=fopen("E:\\demo.txt","w+t"))==NULL){
		puts("file open error!");
		exit(0);
	}
	puts("please enter the student's data:");
	for(int i=0;i<N;i++,ptrA++){
		scanf("%s %d %d %f",ptrA->name,&ptrA->num,&ptrA->age,&ptrA->score);//输入即把数据放入某地址内存,所以别忘了&
	}
	ptrA=stuA;//ptrA在main中为全局变量,别忘了重置指针位置。
	for(int i=0;i<N;i++,ptrA++){
		fprintf(fp,"%s %d %d %f\n",ptrA->name,ptrA->num,ptrA->age,ptrA->score);//写入即把数据写入文件,而不是将地址写入,所以不需要&
	}
	rewind(fp);
	for(int i=0;i<N;i++,ptrB++){
		fscanf(fp,"%s %d %d %f\n",ptrB->name,&ptrB->num,&ptrB->age,&ptrB->score);
	}
	ptrB=stuB;
	for(int i=0;i<N;i++,ptrB++){
		printf("%s %d %d %f\n",ptrB->name,ptrB->num,ptrB->age,ptrB->score);
	}
	fclose(fp);
	return 0;
}

tips:写入的时候是将数据写入文件,而不是将地址写入,取值即可。读出的时候,是将文件数据读出后存储在stuB中,需要存入结构体中内存,即存入内存地址中,需要取地址存储。

6.fseek

int fseek ( FILE *fp, long offset, int origin );

参数说明:

  1. fp 为文件指针,也就是被移动的文件。

  2. offset 为偏移量,也就是要移动的字节数。之所以为 long 类型,是希望移动的范围更大,能处理的文件更大。offset 为正时,向后移动;offset 为负时,向前移动。

  3. origin 为起始位置,也就是从何处开始计算偏移量。C语言规定的起始位置有三种,分别为文件开头、当前位置和文件末尾,每个位置都用对应的常量来表示:
    在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)

#define N 3

struct stu {
	char name[10];
	int num;
	int age;
	float score;
}stuA[N],stuB[N],*ptrA,*ptrB;

int main() {
	FILE* fp;
	ptrA = stuA;
	if ((fp = fopen("E:\\DEMO.TXT", "wb+")) == NULL) {
		puts("file open error!");
		exit(0);
	}
	puts("please enter student's data:");
	for (int i = 0; i < N; i++, ptrA++) {
		scanf("%s %d %d %f", ptrA->name, &ptrA->num, &ptrA->age, &ptrA->score);
	}
	fwrite(stuA, sizeof(struct stu), N, fp);
	fseek(fp, sizeof(struct stu), 0);
	fread(stuB, sizeof(struct stu), 2, fp);
	ptrB = stuB;
	for (int i = 0; i < 2; i++, ptrB++) {
		printf("%s %d %d %f\n", ptrB->name, ptrB->num, ptrB->age, ptrB->score);
	}
	fclose(fp);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值