Skip to content

文件的输入输出(2)

1453字约5分钟

2024-07-07

81.用二进制的方法读写数据

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	FILE *p = fopen("H:/Java/Dos命令5.txt","rb");  //打开方式为r,输出3个ASCII码值,如果打开方式为b,输出4个ASCII码值
	if(p == NULL)
	{
		printf("文件打开失败,程序退出\n");
		exit(-1);
	}
	char ch;
	while((ch = fgetc(p) !=EOF))
		printf("%d\n",ch);
	fclose(p);
	return 0;
}
/*
在windows系统下,使用fputs,fputc,fprintf向一个文件写入数据时,如果写入'\n',文件的打开方式为文本模式,实际上写入的是'\r'和'\n'两个字符
如果文件的打开方式为二进制模式,实际就是写入一个'\n'字符

使用fgetc,fgets,fscanf向一个文件读入数据,如果读到'\r'和'\n',而且文件打开方式为文本模式,会把这两个字符当成一个'\n'读进来
如果文件的打开方式是二进制模式,那么不会发生这种转换,读进来的就是'\n'、'\r'

建议:如果文件本身是一个文本文件,就用文件模式的文件使用方式打开,对这个文件进行读写就用这6个处理字符或者字符串的函数
*/

82.整型是如何在内存中存放的

#include <stdio.h>
typedef union
{
	int a;
	char b[4];
}A;
int main(void)
{
	A c;
	c.b[0]= 'A';
	c.b[1]= 'B';
	c.b[2]= 'C';
	c.b[3]= 'D';
	printf("%d\n",c.a);   //整型数据在内存中是低位在前,高位在后的
	return 0;
}

83.读写文件的注意事项(1)

提示

对二进制文件读写时用fread和fwrite函数,文本文件最好不要用这两个函数进行读写

#include <stdio.h>
#include <stdlib.h>
typedef struct
{
	int a;
	int b;
}A;
int main(void)
{
	A c;
	fread(&c,sizeof(A),1,stdin);    //stadin是标准流文件中的一种,凡是标准流文件的文件使用方式都是”文本模式“,所以这里就会发生字符转换
	printf("%d,%d\n",c.a,c.b);
	return 0;
}

84.rewind函数

//程序功能:让用户通过键盘把数据存放到指定文件末尾,最后再把这个文件输出到屏幕上
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	FILE *p =fopen("H:/Java/Dos命令2/txt","a+");
	if(p == NULL)
	{
		printf("文件打开失败,程序退出\n");
		exit(0);
	}
	char ch;
	while((ch = getc(stdin) != EOF))
		putc(ch,p);

	rewind(p);
	while((ch = getc(p)) != EOF)
		putc(ch,stdout);
	fclose(p);
	return 0;
}

85.fseek函数

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct 
{
	char name[30];
	double score;
}A;
FILE * create(void);
void show(FILE *p)
{
	fseek(p,0L,0);   //等价于 rewind(p);
	A b;
	while(fread(&b,sizeof(A),1,p)== 1)
		printf("学生姓名:%s,成绩:%lf\n",b.name,b.score);
}
int length(FILE *p)
{
	fseek(p,0L,2);
	return ftell(p)/sizeof(A);
}
bool insert(FILE *p,int index)
{
	int len =length(p);
	if(index <1 || index >len+1)
		return false;
	A b;
	for(int i =len-1;i>=index -1;--i)
	{
		fseek(p,i*sizeof(A),0);
		fread(&b,sizeof(A),1,p);
		fseek(p,(i+1)*sizeof(A),0);
		fwrite(&b,sizeof(A),1,p);
	}
		printf("请输入所要插入的学生的姓名和成绩:\n");
		scanf("%s%lf",&b.name,&b.score);
		fseek(p,(index-1)*sizeof(A),0);
		fwrite(&b,sizeof(A),1,p);
		return true;
}
void sort(FILE *p)
{
	int len =length(p);
	for(int i = 0;i<len-1;++i)
	{
		for(int j = 0;j<len-1-i;++j)
		{
			A b1,b2;
			fseek(p,j*sizeof(A),0);
			fread(&b1,sizeof(A),1,p);
			fread(&b2,sizeof(A),1,p);
			if(b1.score > b2.score)
			{
				fseek(p,j*sizeof(A),0);
				fwrite(&b2,sizeof(A),1,p);
				fwrite(&b1,sizeof(A),1,p);
			}
		}
	}
}
int main(void)
{
	FILE *p =create();
//	insert(p,2);
	sort(p);
	show(p);
	fclose(p);
	return 0;
}
FILE *create(void)
{
	FILE *p = fopen("H:/Java/test.abc","wb+");
	if(p == NULL)
	{
		printf("文件打开失败,程序退出\n");
		exit(-1);
	}
	int n;
	A b;
	printf("请输入学生数:");
}

86.文件读写检测——无意义应用

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	FILE *p= fopen("H:/Java/Dos命令5.txt","r");     //该文件没有内容
	if(p == NULL)
	{
		printf("文件打开失败,程序退出\n");
		exit(0);
	}
	if(!feof(p))                                    //错误的使用feof函数判断文件有没有内容,文件结束和错误标志使用fopen函数后自动设置为0,所以这个时候使用feof或者ferror函数的返回值没有任何意义
		printf("这个文件有内容\n");
	else
		printf("这个文件没有内容\n");
	printf("%d\n",ferror(p));
	fclose(p);
	return 0;
}

87.文件读写检测——正确应用

#include <stdio.h>
#include <stdlib.h>
void ce(FILE *p)           //建议每对文件进行I/O操作之后就要检测有没有读写错误,如果有就把这个错误清除
{
	if(ferror(p))
	{
		printf("文件读写错误\n");
		clearerr(p);
	}
}
int main(void)
{
	FILE *p =fopen("H:/Java/Dos命令5.txt","r");
	if(p == NULL)
	{
		printf("文件打开失败,程序退出\n");
		exit(-1);
	}
	putc('A',p);
	ce(p);
	printf("%d\n",ferror(p));    //输出0,因为clearerr会把文件结束标志设置为0,即清除读写错误
	/*
	char ch;
	while(ch = getc(p) !=EOF)    //get函数会在读入错误或者读到文件末尾的时候返回EOF,所以如果文件产生读写错误,则很有可能不会把p所指向的文件的全部内容读进来
		putchar(ch);
	*/
	while(!feof(p))             //这种做法可以把文件中的全部内容读进来输出到屏幕上,只不过末尾会多输出一个值为EOF的文件结束符
	{	
		putchar(getc(p));
		ce(p);
	}
	printf("%d\n",feof(p));
	clearerr(p);
	printf("%d\n",feof(p));
	fclose(p);
	return 0;
}

88.读写文件的注意事项(2)

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	FILE *p = fopen("H:/Java/Dos命令2.txt","r");
	if(p == NULL)
	{
		printf("文件打开失败,程序退出\n");
		exit(-1);
	}
	putchar(getc(p));      //文件的读写是分时进行的,不会一会读一会写,反之亦然。该语句使得文件标记处于读的状态,所以不能进行写的操作
//	rewind(p);
//	fseek(p,1L,0);
	putc('A',p);
	fclose(p);
	return 0;
}
//建议:尽量不要对一个文件既读又写,非常容易出错