1. 为什么使用文件2. 什么是文件3. 文件的打开和关闭4. 文件的顺序读写5. 文件的随机读写6. 文本文件和二进制文件7. 文件读取结束的判定8. 文件缓冲区
目录
struct _iobuf {char * _ptr ;int _cnt ;char * _base ;int _flag ;int _file ;int _charbuf ;int _bufsiz ;char * _tmpfname ;};typedef struct _iobuf FILE ;
FILE * pf ; // 文件指针变量
ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。
// 打开文件FILE * fopen ( const char * filename , const char * mode );// 关闭文件int fclose ( FILE * stream );
- /* fopen fclose example */
- #include
- int main ()
- {
- FILE * pFile;
- //打开文件
- pFile = fopen ("myfile.txt","w");
- //文件操作
- if (pFile!=NULL)
- {
- fputs ("fopen example",pFile);
- //关闭文件
- fclose (pFile);
- }
- return 0;
- }
perror(s) 用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno的值来决定要输出的字符串。
在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用"某些"函数出错时,该函数已经重新设置了errno的值。perror函数只是将你输入的一些信息和errno所对应的错误一起输出。
- #define _CRT_SECURE_NO_WARNINGS 1
- #include
-
- int main()
- {
- //FILE* pf = fopen("mytest.txt", "w");
- FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "r");
- if (pf == NULL) //打开文件失败
- {
- perror("fopen");//打印错误原因
-
- return 1;
- }
- //写文件
-
-
- //关闭文件
- fclose(pf);
- pf = NULL;
-
- return 0;
- }
流:高度抽象的概念
C语言默认打开了以上三种流;
- #define _CRT_SECURE_NO_WARNINGS 1
- #include
-
- //int main()
- //{
- // //FILE* pf = fopen("mytest.txt", "w");
- // FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "w");
- // if (pf == NULL) //打开文件失败
- // {
- // perror("fopen");//打印错误原因
- //
- // return 1;
- // }
- // 写文件
- // //fputc('b', pf);
- // //fputc('i', pf);
- // //fputc('t', pf);
- // //关闭文件
- // fclose(pf);
- // pf = NULL;
- //
- // return 0;
- //}
-
- //int main()
- //{
- // fputc('b', stdout);
- // fputc('i', stdout);
- // fputc('t', stdout);
- // return 0;
- //}
- //
- //
- // 使用fgetc从文件流读取
- //int main()
- //{
- // //FILE* pf = fopen("mytest.txt", "w");
- // FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "r");
- // if (pf == NULL) //打开文件失败
- // {
- // perror("fopen");//打印错误原因
- //
- // return 1;
- // }
- // 读文件
- // int ret = fgetc(pf); //如果读取失败返回 EOF - -1 读文件
- // printf("%c\n", ret);
- // ret = fgetc(pf);
- // printf("%c\n", ret);
- // ret = fgetc(pf);
- // printf("%c\n", ret);
- // //关闭文件
- // fclose(pf);
- // pf = NULL;
- //
- // return 0;
- //}
-
-
- //使用fgetc从标准输入流读取
- int main()
- {
-
- int ret = fgetc(stdin); //如果读取失败返回 EOF - -1 读文件
- printf("%c\n", ret);
- ret = fgetc(stdin);
- printf("%c\n", ret);
- ret = fgetc(stdin);
- printf("%c\n", ret);
-
- return 0;
- }
- int main()
- {
- char arr[10] = { 0 };
- FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "r");
- if (pf == NULL) //打开文件失败
- {
- perror("fopen");//打印错误原因
-
- return 1;
- }
- //读文件
- fgets(arr,4,pf);//最多读到3个 第4个是 \0 - n-1个
- printf("%s\n", arr);
-
- 写文件-按照行来写
- //fputs("abcdef", pf);
- //fputs("qwertyuiop", pf);
-
- //关闭文件
- fclose(pf);
- pf = NULL;
- return 0;
- }
- struct S
- {
- char arr[10];
- int num;
- float sc;
-
- };
-
- //int main()
- //{
- // struct S s = { "abcdef",10,5.5 };
- // //对格式化的数据进行写文件
- // FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "w");
- // if (NULL == pf)
- // {
- // perror("fopen");
- // return 1;
- // }
- // //写文件
- // fprintf(pf, "%s %d %f", s.arr, s.num, s.sc);
- //
- //
- // //关闭文件
- // fclose(pf);
- // pf = NULL;
- // return 0;
- // return 0;
- //}
-
-
- int main()
- {
- struct S s = { "abcdef",10,5.5 };
- //对格式化的数据进行写文件
- FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "r");
- if (NULL == pf)
- {
- perror("fopen");
- return 1;
- }
- //读文件
- fscanf(pf, "%s %d %f", s.arr, &(s.num),&(s.sc));//数组名arr就是首地址
-
- //打印
- printf("%s %d %f\n", s.arr, s.num, s.sc);
- //关闭文件
- fclose(pf);
- pf = NULL;
- return 0;
- return 0;
- }
- //二进制的读写
- struct S
- {
- char arr[10];
- int num;
- float sc;
-
- };
- int main()
- {
- struct S s = { "abcde",10,5.5f };
- 二进制的形式写
- //FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "w");
- //二进制的形式读
- FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "r");
- if (NULL == pf)
- {
- perror("fopen");
- return 1;
- }
- 写文件
- //
- //fwrite(&s, sizeof(struct S), 1, pf);
- //读文件
-
- fread(&s, sizeof(struct S), 1, pf);
- //打印
- printf("%s %d %f\n", s.arr, s.num, s.sc);
-
- //关闭文件
- fclose(pf);
- pf = NULL;
- return 0;
- return 0;
- }
- struct S
- {
- char arr[10];
- int age;
- float f;
- };
-
- int main()
- {
- struct S s = { "hello",20,5.5f };
- struct S tmp={0};
- char buf[100] = { 0 };
- //sprintf 把一个格式化的数据,转换成字符串
- sprintf(buf, "%s %d %f", s.arr, s.age, s.f);//把格式化数据放入字符串buf
- printf("%s\n", buf);
- //从buf字符串中还原出一个结构体数据
- sscanf(buf, "%s %d %f", tmp.arr, &(tmp.age), &(tmp.f));
- printf("%s %d %f\n", tmp.arr, tmp.age, tmp.f);
- return 0;
-
- }
int fseek ( FILE * stream , long int offset , int origin );
- /* fseek example */
- #include
- int main ()
- {
- FILE * pFile;
- pFile = fopen ( "example.txt" , "wb" );
- fputs ( "This is an apple." , pFile );
- fseek ( pFile , 9 , SEEK_SET );
- fputs ( " sam" , pFile );
- fclose ( pFile );
- return 0;
- }
- int main()
- {
- FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "r");
- if(pf==NULL)
- {
- perror("fopen");
- return 1;
- }
- //读取文件
- //int ch=fgetc(pf);
- //printf("%c\n", ch);//a
- //ch = fgetc(pf);
- //printf("%c\n", ch);//b
- //ch = fgetc(pf);
- //printf("%c\n", ch);//c
-
- int ch = fgetc(pf);
- printf("%c\n", ch);//a
- //调整文件指针
- fseek(pf, 2, SEEK_CUR); //SEEK_CUR 当前向前偏移2个
- ch = fgetc(pf);
- printf("%c\n", ch);//d
- //调整文件指针
- fseek(pf, -2, SEEK_END); //SEEK_END 文件末尾\0 向后偏移2个
- ch = fgetc(pf);
- printf("%c\n", ch);//d
- //关闭文件
- fclose(pf);
- pf = NULL;
- return 0;
- }
long int ftell ( FILE * stream );
- /* ftell example : getting size of a file */
- #include
- 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;
- }
void rewind ( FILE * stream );
- /* rewind example */
- #include
- 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]='\0';
- puts (buffer);
- return 0;
- }
- int main()
- {
- FILE* pf = fopen("D:\\Project_All\\C语言\\mytest.txt", "r");
- if(pf==NULL)
- {
- perror("fopen");
- return 1;
- }
- //读取文件
- //int ch=fgetc(pf);
- //printf("%c\n", ch);//a
- //ch = fgetc(pf);
- //printf("%c\n", ch);//b
- //ch = fgetc(pf);
- //printf("%c\n", ch);//c
-
- int ch = fgetc(pf);
- printf("%c\n", ch);//a
- int r = ftell(pf);
- printf("%d\n", r);//相对于起始位置的偏移量 a - 1
- //调整文件指针
- fseek(pf, 2, SEEK_CUR); //SEEK_CUR 当前向前偏移2个
- ch = fgetc(pf);
- printf("%c\n", ch);//d
- //调整文件指针
- fseek(pf, -2, SEEK_END); //SEEK_END 文件末尾\0 向后偏移2个
- ch = fgetc(pf);
- printf("%c\n", ch);//d
-
- int ret = ftell(pf);
- printf("%d\n", ret);//相对于起始位置的偏移量 d - 4
-
- //让文件指针回到起始位置
- rewind(pf);
- ch = fgetc(pf);
- printf("%c\n", ch);//a
- //关闭文件
- fclose(pf);
- pf = NULL;
- return 0;
- }
- #include
- int main()
- {
- int a = 10000;
- FILE* pf = fopen("test.txt", "wb");
- fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
- fclose(pf);
- pf = NULL;
- return 0;
- }
- #include
-
- //0000 0000 0000 0000 0010 0111 0001 0000 2进制
- //00 00 27 10 以16进制形式显示
- int main()
- {
- int a = 10000;
- FILE* pf = fopen("test.txt", "wb");
- if(pf==NULL)
- {
- perror("fopen");
- return 1;
- }
- //写文件
-
- fwrite(&a, sizeof(int), 1, pf);//二进制的形式写到文件中
- fclose(pf);
- pf = NULL;
- return 0;
- }
-
- //写代码把test.txt文件拷贝一份,生成test2.txt
-
- int main()
- {
-
- FILE* pfread = fopen("test.txt", "r");
- if (pfread == NULL)
- {
- return 1;
- }
- FILE* pfwrite = fopen("test2.txt", "w");
- if (pfwrite == NULL)
- {
- fclose(pfread);
- pfread = NULL;
- return 1;
- }
- //文件打开成功
- //读文件
- int ch = 0;
- while ((ch = fgetc(pfread)) != EOF)
- {
- //写文件
- fputc(ch, pfwrite);
- }
- return 0;
- }
- #include
- #include
- 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);
- }
二进制文件的例子:
- #include
- 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 file\n");
- else if (ferror(fp)) {
- perror("Error reading test.bin");
- }
- }
- fclose(fp);
- }
- #include
- #include
- //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;
- }
这里可以得出一个结论: