跟文件操作有关的函数

一、文件顺序读写的函数

1.1fputc函数

将字符(第一个参数)写入pf指向的文件中(pf指向文件对应的文件信息区,pf跟文件里面的内容没有关系),返回写入文件字符的ASCII值,写入失败返回EOF(-1)。
函数声明:

int fputc ( int character, FILE * stream );

使用fputc函数:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
    
    
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//写文件,把26个字母写入文件中
	int i = 0;
	for (i = 0; i < 26; i++)
	{
    
    
		fputc('a' + i, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

因为fputc函数适用于所有输出流,所以也可以写成(stdout替换pf):

fputc('a' + i, stdout);//stdout是标准输出流

1.2fgetc函数

从pf指向的文件中读取字符,返回读取字符的ASCII值,读取失败返回EOF(-1),读完一个字符之后会让文件指针(文件类型指针,这里指向文件里面的内容)向后走一步。
函数声明:

int fgetc ( FILE * stream );

使用fgetc函数:

int main()
{
    
    
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//读文件,把文件中26个字母读到内存中
	int i = 0;
	int ch = 0;
	for (i = 0; i < 26; i++)
	{
    
    
		ch = fgetc(pf);
		printf("%c ", ch);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

因为fgetc函数适用于所有输入流,所以也可以写成(stdin替换pf):

ch = fgetc(stdin);//stdin是标准输出流

1.3fputs函数

第一个参数是字符串的地址;写入成功返回非负值,否则返回EOF(-1)。
函数声明:

int fputs ( const char * str, FILE * stream );

使用fputs函数:

int main()
{
    
    
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//写一行字符串
	fputs("hello world", pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

1.4fgets函数

把读到的内容复制放到第一个参数指向的空间(第一个参数是指针);第二个参数num为放到第一个参数指向的空间的字符的个数,num为10时,实际上读到的有效个数是9个,因为最后\0也算入num中。返回第一个参数指向的空间的地址,读取失败返回NULL。
函数声明:

扫描二维码关注公众号,回复: 15851771 查看本文章
char * fgets ( char * str, int num, FILE * stream );

使用fgets函数:

int main()
{
    
    
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//读一行字符串
	char arr[20] = {
    
     0 };
	fgets(arr, 5, pf);
	printf("%s\n", arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

1.5fprintf函数(格式化输出函数)

函数声明:

int fprintf ( FILE * stream, const char * format, ... );

使用fprintf函数:

struct S
{
    
    
	int n;
	float f;
	char arr[20];
};
int main()
{
    
    
	struct S s = {
    
     100, 3.14f, "zhangsan" };
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//写文件
	fprintf(pf, "%d %f %s\n", s.n, s.f, s.arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

1.6fscanf函数(格式化输入函数)

函数声明:

int fscanf ( FILE * stream, const char * format, ... );

使用fscanf函数:

struct S
{
    
    
	int n;
	float f;
	char arr[20];
};
int main()
{
    
    
	struct S s = {
    
     0 };
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//读文件
	fscanf(pf, "%d %f %s", &(s.n), &(s.f), s.arr);
	printf("%d %f %s\n", s.n, s.f, s.arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

fgetc、fgets、fscanf适用于所有输入流,fputc、fputs、fprintf适用于所有输出流。

1.7sprintf函数(不是顺序读写函数)

函数声明:

int sprintf ( char * str, const char * format, ... );

使用sprintf函数:

struct S
{
    
    
	int n;
	float f;
	char arr[20];
};
int main()
{
    
    
	struct S s = {
    
     200, 3.5f, "wangwu" };
	//把一个结构体中的格式化数据转换成字符串
	char arr[200] = {
    
     0 };
	sprintf(arr, "%d %f %s\n", s.n, s.f, s.arr);
	printf("字符串的数据:%s\n", arr);
	return 0;
}

1.8sscanf函数(不是顺序读写函数)

函数声明:

int sscanf ( const char * s, const char * format, ...);

使用sscanf函数:

struct S
{
    
    
	int n;
	float f;
	char arr[20];
};
int main()
{
    
    
	struct S s = {
    
     200, 3.5f, "wangwu" };
	//把一个结构体中的格式化数据转换成字符串
	char arr[200] = {
    
     0 };
	sprintf(arr, "%d %f %s\n", s.n, s.f, s.arr);
	printf("字符串的数据:%s\n", arr);
	//把一个字符串转换成对应的格式化数据
	struct S tmp = {
    
     0 };
	sscanf(arr, "%d %f %s", &(tmp.n), &(tmp.f), tmp.arr);
	printf("格式化的数据:%d %f %s\n", tmp.n, tmp.f, tmp.arr);
	return 0;
}

1.9三组函数的对比

scanf和printf:scanf是针对标准输入流(stdin)的格式化的输入函数。printf是针对标准输出流(stdout)的格式化的输出函数。
fscanf和fprintf:fscanf是针对所有输入流(文件流/stdin)的格式化的输入函数。fprintf是针对所有输出流(文件流/stdout)的格式化的输出函数。
sscanf和sprintf:sscanf是把字符串转换成格式化的数据的函数。sprintf是把格式化的数据转换成字符串的函数。

1.10fwrite函数(二进制输出函数)

函数声明:

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

使用fwrite函数:

struct S
{
    
    
	char name[20];
	int age;
	float score;
};
int main()
{
    
    
	struct S s = {
    
     "zhangsan", 20, 95.5f };
	FILE* pf = fopen("test.dat", "wb");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//写文件
	fwrite(&s, sizeof(struct S), 1, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

1.11fread函数(二进制输入函数)

返回值为成功读到的元素的个数。
函数声明:

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

使用fread函数:

struct S
{
    
    
	char name[20];
	int age;
	float score;
};
int main()
{
    
    
	struct S s = {
    
     0 };
	FILE* pf = fopen("test.dat", "rb");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//读文件
	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %f\n", s.name, s.age, s.score);
	fclose(pf);
	pf = NULL;
	return 0;
}

二、文件随机读写的函数

2.1fseek函数

函数声明:

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

根据文件指针的位置及其偏移量来定位文件指针(指向文件内容),第3个参数的选择有三种,第一种SEEK_SET(文件指针(指向文件内容)的开始位置),第二种是SEEK_CUR(文件的当前位置),第三种是SEEK_END(文件的末尾位置)。
使用fseek函数,假设文件存放的是abcdef:

int main()
{
    
    
	FILE* pf = fopen("test.dat", "r");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//读文件,内存中存放abcdef
	int ch = fgetc(pf);
	printf("%c\n", ch);//读'a',然后文件指针(指向文件内容)走向下一步
	ch = fgetc(pf);
	printf("%c\n", ch);//读'b'
	ch = fgetc(pf);
	printf("%c\n", ch);//读'c'
	ch = fgetc(pf);
	printf("%c\n", ch);//读'd',这时文件指针指向'e'
	fseek(pf, -3, SEEK_CUR);//这时文件指针指向'e'
	ch = fgetc(pf);
	printf("%c\n", ch);//读到'b'
	fseek(pf, 1, SEEK_SET);//这时文件指针指向'a'
	ch = fgetc(pf);
	printf("%c\n", ch);//读到'b'
	fclose(pf);
	pf = NULL;
	return 0;
}

2.2ftell函数

函数声明:

long int ftell ( FILE * stream );

返回文件指针相对于起始位置的偏移量。
使用ftell函数:

int main()
{
    
    
	FILE* pf = fopen("test.dat", "r");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//读文件,内存中存放abcdef
	int ch = fgetc(pf);
	printf("%c\n", ch);//读'a',然后文件指针(指向文件内容)走向下一步
	ch = fgetc(pf);
	printf("%c\n", ch);//读'b'
	ch = fgetc(pf);
	printf("%c\n", ch);//读'c'
	ch = fgetc(pf);
	printf("%c\n", ch);//读'd',这时文件指针指向'e'
	printf("%d\n", ftell(pf));
	fclose(pf);
	pf = NULL;
	return 0;
}

2.3rewind函数

函数声明:

void rewind ( FILE * stream );

让文件指针的位置回到文件的起始位置。
使用rewind函数:

int main()
{
    
    
	FILE* pf = fopen("test.dat", "r");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//读文件,内存中存放abcdef
	int ch = fgetc(pf);
	printf("%c\n", ch);//读'a',然后文件指针(指向文件内容)走向下一步
	ch = fgetc(pf);
	printf("%c\n", ch);//读'b'
	ch = fgetc(pf);
	printf("%c\n", ch);//读'c'
	ch = fgetc(pf);
	printf("%c\n", ch);//读'd',这时文件指针指向'e'
	rewind(pf);
	printf("%d\n", ftell(pf));
	fclose(pf);
	pf = NULL;
	return 0;
}

三、文件读取结束的判断

3.1feof函数

函数声明:

int feof ( FILE * stream );

当文件读取结束的时候,feof可用来判断文件读取结束的原因是否是遇到文件尾结束。文件读取结束时,fgetc会返回EOF,fgets会返回NULL,fread返回值小于实际要读的个数。
fgetc函数返回值为EOF分析:1、遇到文件末尾返回EOF,同时设置一个遇到文件末尾了的状态,使用feof来检测这个状态。2、遇到错误返回EOF,同时设置一个遇到了错误的状态,使用ferror来检测这个状态。
使用feof函数,文本文件的例子:

int main()
{
    
    
	int c = 0;
	FILE* fp = fopen("test.dat", "r");//文件里保存的是abcdef
	if (!fp)
	{
    
    
		perror("File opening failed");
		return EXIT_FAILURE;//EXIT_FAILURE的定义是1
	}
	while ((c = fgetc(fp)) != EOF)
	{
    
    
		putchar(c);
	}
	printf("\n");
	//判断读取结束的原因
	if (ferror(fp))//如果ferror返回为真则走这里
	{
    
    
		puts("I/O error when reading");
	}
	else if (feof(fp))//如果feof返回为真则走这里
	{
    
    
		puts("End of file reached successfully");
	}
	fclose(fp);
	fp = NULL;
	return 0;
}

使用feof函数,二进制文件的例子:

enum
{
    
    
	SIZE = 5
};
int main()
{
    
    
	double a[SIZE] = {
    
     1.0, 2.0, 3.0, 4.0, 5.0 };
	FILE* fp = fopen("test.dat", "wb");
	fwrite(a, sizeof(*a), SIZE, fp);
	fclose(fp);
	double b[SIZE] = {
    
     0.0 };
	fp = fopen("test.dat", "rb");
	size_t ret = fread(b, sizeof(*b), SIZE, fp);
	if (ret == SIZE)
	{
    
    
		puts("Array read successfully, contents:");
		int n = 0;
		for (n = 0; n < SIZE; n++)
		{
    
    
			printf("%lf ", b[n]);
		}
		putchar('\n');
	}
	else
	{
    
    
		if (feof(fp))//如果feof返回为真则走这里
		{
    
    
			printf("Error reading test.dat:unexpected end of file\n");
		}
		else if (ferror(fp))//如果ferror返回为真则走这里
		{
    
    
			puts("Error reading test.dat");
		}
	}
	fclose(fp);
	fp = NULL;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhanlongsiqu/article/details/129901915