文件的输入输出(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;
}
//建议:尽量不要对一个文件既读又写,非常容易出错