目录
前言
一、文件指针
1.文件打开和关闭
2.打开方式
3.实现代码模板
二、文件顺序读写
1.fputc(从文件里面读一个字符)
2. 三种流
3.fgetc(把一个字符写到文件中)
4.fputs (整行输出)
4.fgets (整行输入)
5..拷贝文件
6. fwrite(将一块内存区域中的数据写入到本地文本)二进制
7.fread(从一个文件流中读取数据)二进制
8.对比以下函数
三、文件随机读写
1.fseek
2.ftell
3 rewind
四、文本文件和二进制文件
五、文件读取结束判定
六、文件缓冲区
总结
前言
为什么使用文件什么是文件
文件的打开和关闭文件的顺序读写文件的随机读写
文本文件和二进制文件文件读取结束的判定文件缓冲区
一、文件指针
1.文件打开和关闭
1
2
3
4//打开文件 FILE * fopen ( const char * filename, const char * mode ); //关闭文件 int fclose ( FILE * stream );
2.打开方式
3.实现代码模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20/* fopen fclose example */ #include <stdio.h> #include <string.h> #include <errno.h> int main () { FILE *pf= fopen ("myfile.txt","w"); //文件操作 if (pf==NULL) { //文件打开失败 printf("%sn",strerror(errno)); return 0; } //写文件 //关闭文件 fclose(pf); pf= NULL; }
二、文件顺序读写
1.fputc(从文件里面读一个字符)
char fputc( char c, FILE *stream );
c:读取的字符
stream:对应的只指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29/* fopen fclose example */ #include <stdio.h> #include <string.h> #include <errno.h> int main () { FILE *pf= fopen ("myfile.txt","w"); //文件操作 if (pf==NULL) { //文件打开失败 printf("%sn",strerror(errno)); return 0; } //写文件 //fput('a',pf); //fput('b',pf); //fput('c',pf); char ch = 0; for(ch = 'a'; ch <= 'z'; ch++){ fputc(ch, pf); } //关闭文件 fclose(pf); pf= NULL; }
结果:
2. 三种流
标准输入流:stdin
标准输出流:stdout
标准错误流 :stderr
从键盘上输入内存时,就是将数据输入到标准输入流
从内存上输入显示器上时,就是将数据输入到标准输出流
使用:将指针替换为所需要的三种流即可。
3.fgetc(把一个字符写到文件中)
int fgetc( FILE*stream );
stream:对应的只指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32/* fopen fclose example */ #include <stdio.h> #include <string.h> #include <errno.h> int main() { FILE* pf = fopen("myfile.txt", "w"); //文件操作 if (pf == NULL) { //文件打开失败 printf("%sn", strerror(errno)); return 0; } //读文件 int ch = fgetc(pf); printf("%cn",ch); int ch = fgetc(pf); printf("%cn", ch); int ch = fgetc(pf); printf("%cn", ch); int ch = fgetc(pf); printf("%cn", ch); //关闭文件 fclose(pf); pf = NULL; }
4.fputs (整行输出)
int fputs(const char *s, FILE *stream);
把参数s指向的字符串写入stream指向的流,但不包括字符串末尾的空字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22/* fopen fclose example */ #include <stdio.h> #include <string.h> #include <errno.h> int main() { FILE* pf = fopen("myfile.txt", "w"); //文件操作 if (pf == NULL) { //文件打开失败 printf("%sn", strerror(errno)); return 0; } //读文件 fputs("hello world",pf); //关闭文件 fclose(pf); pf = NULL; }
4.fgets (整行输入)
char * fgets(char * s, int n,FILE *stream);
从stream指向的输入流中读取 unsigned char 型的字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/* fopen fclose example */ #include <stdio.h> #include <string.h> #include <errno.h> int main() { FILE* pf = fopen("myfile.txt", "w"); //文件操作 if (pf == NULL) { //文件打开失败 printf("%sn", strerror(errno)); return 0; } char buf[1000] = { 0 }; //读文件 fgets(buf, 1000, pf); printf("%s", buf); //关闭文件 fclose(pf); pf = NULL; }
5..拷贝文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include<stdio.h> #include<errno.h> int main()//拷贝文件 { FILE* pr = fopen("text.txt", "r"); if (pr == NULL) { printf("open for read:%sn", strerror(errno)); return 0; } FILE* pw = fopen("text2.txt","w"); if (pr == NULL) { printf("open for write:%sn", strerror(errno)); close(pr); pr = NULL; return 0; } int ch=0; //拷贝文件 while ((ch=fgetc(pr)) != EOF) { fputc(ch, pw); } //关闭文件 fclose(pr); pr == NULL; fclose(pw); pw == NULL; return 0; }
6. fwrite(将一块内存区域中的数据写入到本地文本)二进制
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
-- buffer:指向数据块的指针
-- size:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
-- count:数据个数
-- stream:文件指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18int main() { struct stu s[2] - { {"张三",20,95.5}, { "lisi",16,66.5 } }; FILE* pf = fopen("myfile.txt", "wb"); //文件操作 if (pf == NULL) { //文件打开失败 printf("%sn", strerror(errno)); return 0; } //二进制打开 fwrite(&s, sizeof(struct stu), 2, pf); //关闭文件 fclose(pf); pf = NULL; }
7.fread(从一个文件流中读取数据)二进制
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
-- buffer:指向数据块的指针
-- size:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
-- count:数据个数
-- stream:文件指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21int main() { struct stu s[2] = { 0 }; FILE* pf = fopen("myfile.txt", "rb"); //文件操作 if (pf == NULL) { //文件打开失败 printf("%sn", strerror(errno)); return 0; } //二进制读文件 fread(s, sizeof(struct stu), 2, pf); printf("%s %d %lfn",s[0].name, s[0].age, s[0].d); printf("%s %d %lfn",s[1].name, s[1].age, s[1].d); //关闭文件 fclose(pf); pf = NULL; }
8.对比以下函数
scanf从标准输入流(stdin)上进行格式化输入的函数
printf向标出输出流( stdout)上进行格式化的输出函数
fscanf可以从标准输入流(stdin)/指定的文件流上读取格式化的数据
fprintf把数据按照格式化的方式输出到标准输出流(stdout)/指定的文件流
1
2
3
4
5
6
7
8
9
10
11fscanf()函数(有点像正则表达式): 功 能: 从一个流中执行格式化输入,fscanf遇到空格和换行时结束,注意空格时也结束。 用 法:int fscanf(FILE *stream, char *format,[argument...]); int fscanf(文件指针,格式字符串,输入列表); fscanf(fp,"%s%d%lf",a,&b,&c) 返回值:整型,数值等于[argument...]的个数
1fprintf(pf, "%s %d %s", s.name, s.age, s.sex);//把数据写入文件
sscanf可以从一个字符串中提取(转化)出格式化数据
sprintf把一个格式化的数据转换成字符串
1
2
3int sscanf( const char *buffer, const char *format [, argument ] ... ); int sprintf( char *buffer, const char *format [, argument] ... );
三、文件随机读写
1.fseek
根据文件指针的位置和偏移量来定位文件指针.
1int fseek ( FILE * stream, long int offset, int origin );
描 述: 函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere为基准,偏移offset个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
注意:
第一个参数stream为文件指针
第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.简言之:
fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;
ffseek(fp,-100L,2);把fp指针退回到离文件结尾100字节处。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/* ftell example : getting size of a file */ #include <stdio.h> int main () { FILE * pFile; long size; pFile = fopen ("myfile.txt","rb"); if (pFile==NULL) perror ("Error opening file"); else { fseek (pFile, 0, SEEK_END); // non-portable size=ftell (pFile); fclose (pFile); printf ("Size of myfile.txt: %ld bytes.n",size); } return 0; }
2.ftell
1long ftell(FILE *fp);
返回文件指针相对于起始位置的偏移量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/* ftell example : getting size of a file */ #include <stdio.h> int main () { FILE * pFile; long size; pFile = fopen ("myfile.txt","rb"); if (pFile==NULL) perror ("Error opening file"); else { fseek (pFile, 0, SEEK_END); // non-portable size=ftell (pFile); fclose (pFile); printf ("Size of myfile.txt: %ld bytes.n",size); } return 0; }
3 rewind
1void rewind ( FILE * stream );
让文件指针的位置回到文件的起始位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/* rewind example */ #include <stdio.h> int main () { int n; FILE * pFile; char buffer [27]; pFile = fopen ("myfile.txt","w+"); for ( n='A' ; n<='Z' ; n++) fputc ( n, pFile); rewind (pFile); fread (buffer,1,26,pFile); fclose (pFile); buffer[26]=''; puts (buffer); return 0; }
四、文本文件和二进制文件
二进制文件以二进制形式存储,文本文件以ASCII存储的。
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
1
2
3
4
5
6
7
8
9
10
11
12#include <stdio.h> int main() { int a = 10000; FILE* pf = fopen("test.txt", "wb"); fwrite(&a, 4, 1, pf);//二进制的形式写到文件中 fclose(pf); pf = NULL; return 0; } //0000 0000 0000 0000 0010 0111 0001 0000 // 0 0 0 0 2 7 1 0
二进制结果:
五、文件读取结束判定
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束
1.文本文件读取是否结束,判断返回值是否为EOF ( fgetc),或者NULL) ( fgets)例如:
fgetc判断是否为EOF。
fgets判断返回值是否为NULL。
2.二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。例如:
fread判断返回值是否小于实际要读的个数。
文本文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#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); } //判断是什么原因结束的 //IO错误 if (ferror(fp)) puts("I/O error when reading"); //判断是否是读到文件末尾 else if (feof(fp)) puts("End of file reached successfully"); fclose(fp); }
二进制文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <stdio.h> enum { SIZE = 5 }; int main(void) { double a[SIZE] = {1.,2.,3.,4.,5.}; FILE *fp = fopen("test.bin", "wb"); // 必须用二进制模式 fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组 fclose(fp); double b[SIZE]; fp = fopen("test.bin","rb"); size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组 if(ret_code == SIZE) { puts("Array read successfully, contents: "); for(int n = 0; n < SIZE; ++n) printf("%f ", b[n]); putchar('n'); } else { // error handling //判断是否读到文件错误 if (feof(fp)) printf("Error reading test.bin: unexpected end of filen"); //判断是否读到文件末尾 else if (ferror(fp)) { perror("Error reading test.bin"); } } fclose(fp); }
六、文件缓冲区
从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <stdio.h> #include <windows.h> //VS2013 WIN10环境测试 int main() { FILE*pf = fopen("test.txt", "w"); fputs("abcdef", pf);//先将代码放在输出缓冲区 printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容n"); Sleep(10000); printf("刷新缓冲区n"); fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘) //注:fflush 在高版本的VS上不能使用了 printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了n"); Sleep(10000); fclose(pf); //注:fclose在关闭文件的时候,也会刷新缓冲区 pf = NULL; return 0; }
因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件,如果不做,可能导致读写文件的问题。
总结
可以更新通讯录文件操作部分。
最后
以上就是长情小熊猫最近收集整理的关于《C语言初阶进阶完整教程》- 已完结 - 文件操作前言一、文件指针二、文件顺序读写 4.fputs (整行输出)三、文件随机读写 四、文本文件和二进制文件 五、文件读取结束判定 六、文件缓冲区 总结的全部内容,更多相关《C语言初阶进阶完整教程》-内容请搜索靠谱客的其他文章。
发表评论 取消回复