目录
1.文件的打开与关闭;
打开文件;
关闭文件;
2.文件的打开方式;
“r”(只读);
“w”(只写);
3.文件的顺序读写;
字符输入函数fgetc
代码1:
代码2(标准输入流):
字符输出函数fputc
代码1(文件输出流):
代码2(标准输出流):
文本行输入函数fgets
代码1(文件输入流):
代码2(标准输入流):
文本行输出函数fputs
代码1(文件输出流):
代码2(标准输出流):
格式化输入函数fscanf
代码1(文件输入流):
代码2(标准输入流):
格式化输出函数fprintf
代码1(文件输入流):
代码2(标准输出流):
sscanf和sprintf
代码:
二进制输入fread
代码:
二进制输出fwrite
代码:
4.文件的随机读写;
fseek:
简要介绍:
代码举例:
代码分析:
运行结果:编辑
ftell:
简要介绍:
代码举例:
代码分析:
运行结果:
rewind:
简要介绍:
代码举例:
代码分析:
运行结果:
5.文件结束判断;
用途:
代码举例:
代码分析:
运行结果:
6.文件缓冲区;
简要介绍:
代码举例:
代码分析:
运行结果:
1.文件的打开与关闭;
打开文件;
FILE * fopen ( const char * filename, const char * mode );
关闭文件;
int fclose ( FILE * stream);
2.文件的打开方式;
“r”(只读);
为了输入数据,打开一个已经存在的文本文件;如果指定文件不存在会出错;
#include <stdio.h>
int main()
{
FILE* pFile;
//打开文件
pFile = fopen("myfile.txt", "r");
//文件操作
fclose(pFile);
return 0;
}
代码分析:
从图中看,文件夹所在位置并没有要读的文件,所以运行结果应该是出现错误;
“w”(只写);
为了输出数据,打开一个文本文件;如果指定文件不存在会建立一个新的文件;
#include <stdio.h>
int main()
{
FILE* pFile;
//打开文件
pFile = fopen("myfile.txt", "w");
//文件操作
if (pFile != NULL)
{
fputs("fopen example", pFile);
//关闭文件
fclose(pFile);
}
return 0;
}
代码分析:
这里文件的使用方式是只写,有这个文件就打开这个文件,没有就创建这个文件,然后判断是否是空指针,如果不是,用fputs将字符串写入这个文件,关闭文件;
3.文件的顺序读写;
字符输入函数fgetc
适用于所有输入流;
代码1:
#include<stdio.h>
int main()
{
FILE* pf = fopen("data.text", "r");///要读文件
if (NULL == pf)//现在是相对路径,在现在的路径下;
{
perror("fopen->pf");//因为源c所在的位置没有data.text
return;
}
//从文件顺序往后读;
int ch=fgetc(pf);//给data写字符;
printf("%c\n", ch);
ch = fgetc(pf);//给data写字符;
printf("%c\n", ch);
ch = fgetc(pf);//给data写字符;
printf("%c\n", ch);
ch = fgetc(pf);//给data写字符;
printf("%c\n", ch);
fclose(pf);
pf = NULL;//否则置为野指针;
return 0;
}
代码1分析:
在data.text文件内输入abcd,以只读的文件使用方式打开文件,并判断返回的是否是空指针;如果不是空指针,使用fgetc函数读取字符并放在ch里,打印出来;
运行结果:
代码2(标准输入流):
#include<stdio.h>
int main()
{
FILE* pf = fopen("data.txt", "r");///要读文件
if (NULL == pf)//现在是相对路径,在现在的路径下;
{
perror("fopen->pf");//因为源c所在的位置没有data.text
return;
}
//从键盘顺序往后读
int ch = fgetc(stdin);//给data写字符;
printf("%c\n", ch);
ch = fgetc(stdin);//给data写字符;
printf("%c\n", ch);
ch = fgetc(stdin);//给data写字符;
printf("%c\n", ch);
ch = fgetc(stdin);//给data写字符;
printf("%c\n", ch);
fclose(pf);
pf = NULL;//否则置为野指针;
return 0;
}
代码2分析:
fgetc从键盘上的得到数据,并打印;
字符输出函数fputc
适用于所有输出流;
代码1(文件输出流):
#include<stdio.h>
int main()
{
FILE* pf = fopen("light.text", "w");//文件不存在就创建一个;
if (NULL == pf)//现在是相对路径,在现在的路径下;
{
perror("fopen->pf");//因为源c所在的位置没有data.text
return;
}
fputc('a', pf);//给data写字符;
fputc('b', pf);//每次写完之后,文件指针向后偏移一个;
fputc('c', pf);
fclose(pf);
pf = NULL;//否则置为野指针;
return 0;
}
代码1分析:
打开一个文件,以只写的方式,判断是否是空指针;如果不是空指针,使用fputc把字符放到文件里;
代码2(标准输出流):
#include<stdio.h>
int main()
{
FILE* pf = fopen("light.text", "w");//文件不存在就创建一个;
if (NULL == pf)//现在是相对路径,在现在的路径下;
{
perror("fopen->pf");//因为源c所在的位置没有data.text
return;
}
int i = 0;
for (i = 0;i < 26;i++)
{
fputc('a' + i, stdout);//这里stdout是标准输出,在屏幕上;
}
fclose(pf);
pf = NULL;//否则置为野指针;
return 0;
}
代码2分析:
使用fputc,将字符输出到屏幕上;
文本行输入函数fgets
适用于所有输入流;
代码1(文件输入流):
#include <stdio.h>
int main()
{
FILE* x=fopen("data.txt", "r");
if (NULL == x)
{
perror("fopen");
return;
}
char arr[10] = { 0 };
fgets(arr,10,x);//x是从哪读,10 是读几个,arr是读了放到那;读的时候遇到换行不读,读到10-1加\n结束;
printf("%s\n", arr);
fgets(arr, 10, x);//x是从哪读,10 是读几个,arr是读了放到那;读的时候遇到换行不读,读到10-1加\n结束;
printf("%s\n", arr);
fclose(x);
x = NULL;
return 0;
}
代码1分析:
文件里字符的安放:
fgets规则:遇到换行不读;读到第n-1个字符后,后面直接换行结束;
代码2(标准输入流):
#include <stdio.h>
int main()
{
FILE* x=fopen("data.txt", "r");
if (NULL == x)
{
perror("fopen");
return;
}
char arr[10] = { 0 };
//从屏幕上读
fgets(arr, 10, stdin);//x是从哪读,10 是读几个,arr是读了放到那;读的时候遇到换行不读,读到10-1加\0结束;
printf("%s\n", arr);
fgets(arr, 10, stdin);//x是从哪读,10 是读几个,arr是读了放到那;读的时候遇到换行不读,读到10-1加\0结束;
printf("%s\n", arr);
fclose(x);
x = NULL;
return 0;
}
代码2分析:
fgets:从键盘上读10个字符存入arr;
文本行输出函数fputs
适用于所有输入流;
代码1(文件输出流):
#include <stdio.h>
int main()
{
FILE* x=fopen("data.txt", "w");
if (NULL == x)
{
perror("fopen");
return;
}
char arr[10] = { 0 };
fputs("light abc\n", x);//换行\n;
fputs("light adc", x);//只是一行;打印文件里;
fclose(x);
x = NULL;
return 0;
}
代码1分析:
fputs函数把字符串输入到文件里;
代码2(标准输出流):
#include <stdio.h>
int main()
{
FILE* x=fopen("data.txt", "w");
if (NULL == x)
{
perror("fopen");
return;
}
char arr[10] = { 0 };
fputs("light abc\n", stdout);//打印屏幕上;
fputs("light adc",stdout);
fclose(x);
x = NULL;
return 0;
}
代码2分析:
fputs把字符串输入到屏幕上;
格式化输入函数fscanf
适用于所有输入流;
代码1(文件输入流):
#include<stdio.h>
struct S
{
int age;
float height;
};
int main()
{
/*FILE* x = fopen("data.text", "w");*///以写的方式;
FILE* x = fopen("data.txt", "r");//以读的方式
if (NULL == x)
{
perror("fopen");
return;
}
struct S a = {0};
fscanf(x, "%d %f", &(a.age), &(a.height));//读到的放到a里面;
printf("%d %f", a.age, a.height);
fclose(x);
x = NULL;
return 0;
}
代码1分析:
以只读的方式打开文件,判断是否是空指针;如果不是,使用fscanf函数,从文件里格式化形式读取文件,读到的结果放到a中;
代码2(标准输入流):
#include<stdio.h>
struct S
{
int age;
float height;
};
int main()
{
/*FILE* x = fopen("data.text", "w");*///以写的方式;
FILE* x = fopen("data.txt", "r");//以读的方式
if (NULL == x)
{
perror("fopen");
return;
}
struct S a = {0};
fscanf(stdin, "%d %f", &(a.age), &(a.height));//从屏幕上读,读到的放到a里面;
printf("%d %f", a.age, a.height);
fclose(x);
x = NULL;
return 0;
}
代码2分析:
从键盘上读取数据,格式化的形式放到a中;
格式化输出函数fprintf
适用于所有输出流;
代码1(文件输入流):
#include<stdio.h>
struct S
{
int age;
float height;
};
int main()
{
FILE* x = fopen("data.text", "w");//以写的方式;
if (NULL == x)
{
perror("fopen");
return;
}
struct S a = { 18,1.78f };//写文件的时候
//写文件
fprintf(x, "%d %f", a.age, a.height);//存到x里面;
fclose(x);
x = NULL;
return 0;
}
代码1分析:
将a中的内容格式化形式放到x里;
代码2(标准输出流):
#include<stdio.h>
struct S
{
int age;
float height;
};
int main()
{
FILE* x = fopen("data.text", "w");//以写的方式;
if (NULL == x)
{
perror("fopen");
return;
}
struct S a = { 18,1.78f };//写文件的时候
//写文件
fprintf(stdout, "%d %f", a.age, a.height);
fclose(x);
x = NULL;
return 0;
}
代码2分析:
将a中的内容格式化输出到屏幕上;
sscanf和sprintf
代码:
#include<stdio.h>
struct s
{
int age;
float height;
char name[10];
};
int main()
{
struct s abc = { 18,.name = "abc",.height = 1.78f };
struct s tem = { 0 };
char name1[30] = { 0 };
sprintf(name1, "%d %f %s", abc.age, abc.height, abc.name);//把abc的内容以中间要求的格式变成字符串存到name1里;
printf("%s", name1);
sscanf(name1,"%d %f %s",&(tem.age),&(tem.height),&(tem.name));//把字符串name1中的字符串以格式化的形式给结构变量tem
printf("%d %f %s", tem.age, tem.height, tem.name);
return 0;
}
代码分析:
sscanf:从字符串中读取格式化数据;sprintf:将格式化的数据转为字符串;将abc中的内容以格式化的形式放到name1里,形成字符串,打印出来;再将name1的字符串以格式化的方式放到tem中,打印出来;
二进制输入fread
适用于文件;
代码:
#include<stdio.h>
struct s
{
int age;
float height;
char name[10];
};
int main()
{
FILE* x = fopen("data1.text", "rb");
if (NULL == x)
{
perror("fopen");
return;
}
struct s aw = { 0 };
fread(&aw, sizeof(struct s), 1, x);//写到aw文件里; //返回读到的个数;
printf("%d %f %s", aw.age, aw.height, aw.name);//打印观察效果;
fclose(x);
x = NULL;
return 0;
}
代码分析:
事先写入二进制文件(fwrite的运行结果图),将x中内容写到aw中;
二进制输出fwrite
适用于文件;
代码:
#include<stdio.h>
struct s
{
int age;
float height;
char name[10];
};
int main()
{
FILE* x = fopen("data1.text", "wb");
if (NULL == x)
{
perror("fopen");
return;
}
struct s aw = { 15,1.78f,"daaf" };
fwrite(&aw,sizeof(struct s),1,x);//写到x文件里;
return 0;
}
代码分析:
以二进制只写的方式打开文件,判断是否是空指针;不是的话,将aw中的内容写到x里;这里sizeof()是要写数据的类型大小;1是表示写几个;
4.文件的随机读写;
fseek:
简要介绍:
int fseek ( FILE * stream, long int offset, int origin );stream是文件指针;offset是偏移量,+表示往右偏移,-表示往左偏移;origin:共有三种:
SEEK_SET Beginning of file SEEK_CUR Current position of the file pointer SEEK_END End of file *
代码举例:
#include<stdio.h>
int fseek ( FILE * stream, long int offset, int origin );//起始位置偏移0就可以得到起始位置
//通过fseek定位指针;
int main()
{
FILE* x = fopen("data.text", "r");
int ch = fgetc(x);//一开始默认在开头
printf("%c\n", ch);
ch = fgetc(x);
printf("%c\n", ch);
ch = fgetc(x);
printf("%c\n", ch);
ch = fgetc(x);
printf("%c\n", ch);//abcd efghi
fseek(x, 2, SEEK_CUR);//2表示右移
ch = fgetc(x);//g
printf("%c\n", ch);
fseek(x, -3, SEEK_CUR);
ch = fgetc(x);//e
printf("%c\n", ch);
fclose(x);
x = NULL;
}
代码分析:
这是文件里的内容,指向a的前面,读一次,打印a,偏移一位,一连读了四位,打印 a b
c d,现在指向d的后方,再从现在的位置向右偏移2,指向f的前面,读一个字符,打印出f,指向h的前面,再从现在的位置左移3,指向d的后面,读取一个空格字符;
运行结果:
ftell:
简要介绍:
long int ftell ( FILE * stream ); 返回的是文件指针相当于起始位置的偏移量;
代码举例:
int main()
{
FILE* x = fopen("data.text", "r");
int ch = fgetc(x);//一开始默认在开头
long int size = ftell(x);
printf("%ld\n", size);
ch = fgetc(x);
size = ftell(x);
printf("%ld\n", size);
ch = fgetc(x);
size = ftell(x);
printf("%ld\n", size);
ch = fgetc(x);
size = ftell(x);
printf("%ld\n", size);
fseek(x, 2, SEEK_CUR);//2表示右移
ch = fgetc(x);//g
size = ftell(x);
printf("%ld\n", size);
fclose(x);
x = NULL;
}
代码分析:
一开始偏移量是0,读一个字符偏移量加1,读完前四个字符,偏移量依次是1、2、3、4,再使用fseek将指针的位置往后偏移2,此时偏移量是6,再读一个字符,偏移量是7;
运行结果:
rewind:
简要介绍:
void rewind ( FILE * stream ); 让文件指针的位置回到文件的起始位置;
代码举例:
int main()
{
FILE* x = fopen("data.text", "r");
int ch = fgetc(x);//一开始默认在开头
printf("%c\n", ch);
rewind(x);
ch = fgetc(x);//一开始默认在开头
printf("%c\n", ch);
rewind(x);
ch = fgetc(x);//一开始默认在开头
printf("%c\n", ch);
rewind(x);
ch = fgetc(x);//一开始默认在开头
printf("%c\n", ch);
rewind(x);
ch = fgetc(x);//一开始默认在开头
printf("%c\n", ch);
rewind(x);
fclose(x);
x = NULL;
}
代码分析:
这是文件里的内容,打开文件,判断指针是否是空指针,不是的话,使用fgetc读取字符,读完一个打印,然后让指针回到起始位置,再读,再打印,再让指针回到起始位置,共循环五次;
运行结果:
5.文件结束判断;
用途:
fgetc 判断是否为EOF 。
fgets 判断返回值是否为 NULL 。
代码举例:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c; // 注意:int,非char,要求处理EOF
FILE* fp = fopen("test.txt", "r");
if (!fp) {
perror("File opening failed");
return EXIT_FAILURE;
}
//fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
{
putchar(c);
}
//判断是什么原因结束的
if (ferror(fp))
puts("I/O error when reading");
else if (feof(fp))
puts("End of file reached successfully");
fclose(fp);
}
代码分析:
先打开文件,判断指针是否是空指针;如果不是,进入while循环,如果fgetc返回的不是EOF,打印出c;跳出循环,判断是什么原因,先判断是否输入输出时错误,属于读取失败结束;再判断读取结束的原因,如果返回不等于0的数说明到了文件尾结束;
运行结果:
6.文件缓冲区;
简要介绍:
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
代码举例:
#include <stdio.h>
#include <windows.h>
//VS2013 WIN10环境测试
int main()
{
FILE*pf = fopen("temt.txt", "w");
fputs("abcdef", pf);
printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
Sleep(10000);
printf("刷新缓冲区\n");
fflush(pf);
printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
Sleep(10000);
fclose(pf);
pf = NULL;
return 0;
}
代码分析:
先打开文件,放入字符串abcdef,此时文件里没有内容,睡眠,使用fflush时会刷新缓冲区,数据会传送,此时打开文件会有内容;fclose时也会刷新缓冲区;