c文件的有关基本知识
**************************************************************************************************************
什么是文件?
1.程序文件:包括源程序文件(后缀.c)、目标文件(后缀.obj)、可执行文件(后缀.exe)等。这种文件的内容是程序代码。
2.数据文件:供程序运行时读写的数据。
文件名
文件名包括3部分:1.文件路径、2.文件名主干、3.文件后缀。
例如:"D:\桌面\test.txt" ------- ”D:\桌面“为1,”test“为2,”txt“为3.
数据文件
(整数16在内存中的存储形式00000000 00000000 00000000 00010000)
1.ASCII文件(文本文件):存取文件内容需要转换-----例如16存储为00110001 00110110 ASCII形式。
2.二进制文件(镜像文件):存取文件内容不需要转换---例如16存储为00000000 00000000 00000000 00010000 二进制形式
文件类型指针
在stdio.h中被声明:FILE * fp;
打开和关闭文件
使用文件方式:
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
”r“(只读) | 为了输入数据,打开一个已存在的文本文件 | 报错 |
”w“(只写) | 为了输出数据,打开一个文本文件(如果文件含义内容,打开后会清空) | 创立新文件(如果路径含有未创建的文件夹,也会报错) |
”a“(追加) | 向文本文件尾添加数据,文件位置标记位于末尾 | 报错 |
”rb“(只读) | 为了输入数据,打开一个已存在的二进制文件 | 报错 |
”wb“(只写) | 为了输出数据,打开一个二进制文件(如果文件含义内容,打开后会清空) | 创立新文件(如果路径含有未创建的文件夹,也会报错) |
”ab“(追加) | 向二进制文件尾添加数据,文件位置标记位于末尾 | 报错 |
如果想要同时可读可写,在每项后添一个”+“即可。例如:r+,w+,a+.......
打开和关闭文件函数
1.打开文件:fopen(文件名,使用文件方式); 打开成功返回文件起始地址的指针,打开失败返回NULL或者说是0
2.关闭文件:fclose(文件指针); 关闭成功返回0,关闭失败返回EOF或者说-1
顺序读写文件
向文件读写字符
函数 | 功能 | 返回值 |
---|---|---|
fgetc(fp) | 从fp所指向的文件读入一个字符 | 成功:带回所读字符 失败:EOF(或-1) |
fputc(ch,fp) | 把字符ch写到文件指针变量fp所指的文件中 | 成功:返回值是输出的字符 失败:返回EOF(或-1) |
feof(fp) | 如果fp所指位置文件的文件位置标记到达文件末尾则返回1,否则返回0 |
下面用将a文件中内容复制到b文件的一段代码演示上面所学到的内容
#include<stdio.h>
#include<stdlib.h>
int main(){
//创建文件类型指针指向要操作的文件
FILE * fp=fopen("D:\\桌面\\test.txt","r");
//判断文件是否打开成功,失败就退出程序
if(fp==NULL){
printf("文件打开失败,程序退出");
//exit退出程序的函数,0表示程序正常结束;非0表示程序异常,终止程序(在stdlib.h中调用)
//或者不使用exit函数,使用return一个值来表示文件打开失败也可以
//例如 return 1 当调用这段程序得到返回值为一就可以知道是文件打开失败
exit(-1);
}
FILE * fp2=fopen("D:\\桌面\\test2.txt","w");
if(fp2==NULL){
printf("文件打开失败,程序退出");
exit(-1);
}
//定义一个ch存储读取的字符
char ch;
//循环从fp所指文件中读字符,同时写字符到fp2所指文件
while((ch=fgetc(fp))!=EOF){
fputc(ch,fp2);
}
//关闭文件
fclose(fp);
fclose(fp2);
return 0;
}
向文件读写一个字符串
函数 | 功能 | 返回值 |
---|---|---|
fgets(str,n,fp) | 从fp所指向的文件读入一个长度未(n-1)的字符串,存放到字符数组str中。如果在读完n-1个字符之前遇到 '\n'或结束符EOF,读取结束。只能读n-1个字符是因为最后会加'\0'占用了一个字符空间。 | 成功:返回地址str 失败:NULL |
fputs(str,fp) | 把str所指的字符串写到文件指针变量fp所指的文件中 | 成功:返回0 失败:返回非0 |
演示代码:
#include<stdio.h>
int main(){
/*所读的文件内容:
123456
123456789abcdefg
*/
//创建字符数组存放读取的字符串
char a[10];
FILE *fp= fopen("D:\\桌面\\test2.txt","r");
if(fp==NULL){
printf("打开文件失败,程序退出");
return 1; //这里写返回一个值来判定也可以,若使用exit就要记得库stdlib.h
}
//把文件读取进来,输出到控制台
fgets(a,10,fp);
fputs(a,stdout); //第一次输出:"123456\n" ,读到换行符,gets函数结束读取
fgets(a,10,fp);
fputs(a,stdout); //第二次输出:"123456789" ,读到最大长度10-1=9,gets函数结束读取
fgets(a,10,fp);
fputs(a,stdout); //第三次输出:"abcdefg" ,读到EOF(文件末尾),gets函数结束读取
//使用循环将文件全部打印到控制台
// while((fgets(a,10,fp))!=NULL){
// //这里stdout是标准输出流,表示输出信息到我们的终端
// fputs(a,stdout);
// }
fclose(fp);
fp=NULL; //将fp设置为NULL可以避免野指针的出现
}
利用fgets和fputs从键盘输入到控制台代码实现
#include<stdio.h>
int main(){
//创建字符数组存放读取的字符串
char a[10];
FILE *fp= fopen("D:\\桌面\\test2.txt","r");
if(fp==NULL){
printf("打开文件失败,程序退出");
return 1;
}
//把从键盘输入的内容输出到控制台
//stdin:指向标准输入流;stdout:指向标准输出流
//windows系统按下ctrl+z(EOF)再回车来结束
while(fgets(a,10,stdin)!=NULL){
fputs(a,stdout);
}
fclose(fp);
fp=NULL;
}
用格式化的方式读写文件
这两个函数输入时要将ASCII码转换为二进制,输出要将二进制转为ASCII码,效率较低。
1.读:fscanf(文件指针,格式字符串,输入表列);
2.写:fprintf(文件指针,格式字符串,输出表列);
代码示例:
#include<stdio.h>
/*
文件内容:
abcd
123
3.14
*/
int main(){
//创建字符数组存放读取的字符串
char a[10];
int b;
double c;
FILE *fp= fopen("D:\\桌面\\test2.txt","r");
if(fp==NULL){
printf("打开文件失败,程序退出");
return 1;
}
FILE *fp2= fopen("D:\\桌面\\test3.txt","w");
if(fp==NULL){
printf("打开文件失败,程序退出");
return 1;
}
//格式化输入,从test2文件中读到数据
fscanf(fp,"%s%d%lf",a,&b,&c);
printf("%s\n%d\n%lf",a,b,c);
/*控制台输出:abcd
123
3.140000*/
//格式化输出,写到文件test3中
fprintf(fp2,"%s\n%d\n%lf",a,b,c);
fclose(fp);
fclose(fp2);
fp=NULL;
fp2=NULL;
}
用二进制方式向文件读写一组数据
函数 | 功能 | 返回值 |
fread(buffer,size,count,fp) | 从fp所指的文件读数据,最多读count个项,每项size个字节,并把这些数据存放到以buffer为地址开头的内存块中 | 如果调用成功返回读取项个数,如果不成功或者读到文件末尾返回0 |
fwrite(buffer,size,count,fp) | 把以buffer开头的地址块中count项size个字节的数据读到fp所指的文件中 | 返回实际写入项数count |
示例代码
#include<stdio.h>
typedef struct{
char name[30];
int score;
}Stu;
int main(){
Stu a[3]={{"xiaoming",89},{"xiaoli",92},{"shangpao",99}};
FILE *fp= fopen("D:\\桌面\\test4.abc","wb");
if(fp==NULL){
printf("打开文件失败,程序退出");
return 1;
}
fwrite(a,sizeof(Stu),3,fp);
fclose(fp);
fp= fopen("D:\\桌面\\test4.abc","rb");
if(fp==NULL){
printf("打开文件失败,程序退出");
return 1;
}
Stu b[3];
fread(b,sizeof(Stu),3,fp);
for(int i=0;i<3;i++){
printf("学号:%d 姓名:%s 成绩:%d\n",i+1,b[i].name,b[i].score);
}
fclose(fp);
}
读写文件的注意事项
在Windows系统中,文本模式下,文件以'\r''\n'代表换行。若在文本模式打开文件,并用fgetc、fputc等函数写入'\n',系统会自动在'\n'前加上'\r'。即实际写的内容是'\r''\n'。在二进制模式打开时,使用fgetc、fputc函数读写'\n'时,会把'\r''\n'当成两个字符来进行操作。而在文本模式下只会当作一个。
代码示例
#include<stdio.h>
/*
文件内容:
a
b
*/
int main(){
//定义ch存储读取到的字符
char ch;
//以二进制模式打开文件
FILE * fp1=fopen("D:\\桌面\\test.txt","rb");
if(fp1==NULL){
printf("文件打开失败");
return 1;
}
//读取文件内容并输出
while((ch=fgetc(fp1))!=EOF){
printf("%d\n",ch);
}
/*
输出内容:
97 //97代表是a
13 //13代表是\r
10 //10代表是\n
98 //98代表是b
*/
fclose(fp1);
fp1=NULL;
//以文本模式打开文件
FILE * fp2=fopen("D:\\桌面\\test.txt","r");
if(fp2==NULL){
printf("文件打开失败");
return 1;
}
while((ch=fgetc(fp2))!=EOF){
printf("%d\n",ch);
}
/*
输出内容:
97 //97代表是a
10 //10代表是\r\n
98 //98代表是b
*/
fclose(fp2);
fp2=NULL;
}