C语言之文件详解

阅读: 评论:0

C语言之文件详解

C语言之文件详解

  1. 一般在程序设计中的文件类型有两种:程序文件、数据文件。

  2. 程序文件:包括源程序文件(.c)、目标文件(.obj)、可执行文件(.exe)

  3. 数据文件:该文件的内容不是程序,而是程序运行时读写的数据。本篇博客就是对数据文件的操作的讨论。

1.文件名

  • 文件名是一个文件的唯一标识,用于识别和引用该文件。
  • 文件名包含3个部分:文件路径+文件名主干+文件后缀
  • 如:D:。

2.文件类型

  1. 文本文件:数据在内存中以二进制形式存储,若要求在外存上以ASCII码的形式存储,则需要存储前转换。该种以ASCII字符的形式存储的文件就是文本文件。
  2. 二进制文件:数据在内存中以二进制形式存储,若不加转换依旧以二进制形式的输出到外存中,该文件即二进制文件。

3.文件缓冲区

  • ANSIC标准采用缓冲文件系统处理的数据文件的。
  • 缓冲文件系统:指系统自动地在内存种为程序种每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区。缓冲区的大小根据C编译系统决定的。

4.文件指针

  • 每个被使用的文件在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息,这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名为FILE。
struct _iobuf{char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;
};
typedef struct _iobuf FILE;
  • 创建一个FILE的指针变量: FILE pf;
  • 可以通过文件指针变量找到与它关联的文件。

5.文件的打开关闭

  • 文件在读写之前应该先打开文件,在读写之后使用该文件结束之后应该关闭文件。

(1)数据文件的打开

  • fopen
  • FILE * fopen ( const char * filename, const char * mode );
  • 打开一个文件
  • 成功返回该文件的文件指针,失败返回空指针。

(2)数据文件的关闭

  • fclose
  • int fclose(FILE *stream);
  • 关闭一个文件
  • 成功返回0,失败返回EOF(文件结束标识符,-1)
//mode:打开方式
"r"(只读,覆盖写):为了输入数据,打开一个已经存在的文本文件。如果指定文件不存在则出错。"w"(只写):为了输出数据,打开一个文本文件。如果指定文件不存在则建立一个新的文件。"a"(追加写):向文本文件尾添加数据。如果指定文件不存在则出错。"rb"(只读,覆盖写):为了输入数据,打开一个二进制文件。如果指定文件不存在则出错。"wb"(只写):为了输出数据,打开一个二进制文件。如果指定文件不存在则建立一个新的文件。"ab"(追加写):向一个二进制文件尾添加数据。如果指定文件不存在则出错。"r+"(读写):为了读和写,打开一个文本文件。如果指定文件不存在则出错。"w+"(读写):为了读和写,建立一个新的文件。如果指定文件不存在则建立一个新的文件。"a+"(读写):打开一个文件,在文件尾进行读写。如果指定文件不存在则建立一个新的文件。"rb+"(读写):为了读和写打开一个二进制文件。如果指定文件不存在则出错。"wb+"(读写):为了读和写,新建一个新的二进制文件。如果指定文件不存在则建立一个新的文件。"ab+"(读写):打开一个二进制文件,在文件尾进行读和写。如果指定文件不存在则建立一个新的文件。
#include <stdio.h>int main()
{FILE *pf;pf = fopen(&#", "w");//以只写模式打开,若不存在该文件则创建。if (pf != NULL){fclose(pf);}return 0;
}

6.文件的读写

(1)数据文件的顺序读写

①fgetc

  • int fgetc ( FILE * stream );
  • 字符输入函数,从文件中读取一个字符,适用于所有输入流。
  • 成功返回读取的字符(提升为int型),失败返回EOF(文件结束标识符,-1)
#include <stdio.h>int main()
{FILE *pf;int c;pf = fopen(&#", "r");//以只读模式打开,上面已经创建了该文件。while ((c = fgetc(pf)) != EOF){printf("%c ", c);}printf("n");fclose(pf);return 0;
}


②fputc

  • int fputc ( int character, FILE * stream );
  • 字符输出函数,将字符输入到文件指针指向的指定文件中,适用于所有输出流。
  • 成功返回写入的字符(提升为int型),失败返回EOF(文件结束标识符,-1)
#include <stdio.h>int main()
{FILE *pf;int c;pf = fopen(&#", "a");//以追加写模式打开,上面已经创建了该文件。fputc('I', pf);fclose(pf);pf = fopen(&#", "r");//以只读模式打开while ((c = fgetc(pf)) != EOF){printf("%c ", c);}printf("n");fclose(pf);return 0;
}


③fgets

  • char * fgets ( char * str, int num, FILE * stream );
  • 文本行输入函数,从文件中读取数据,读到换行符为止,适用于所有输入流。从文件中读到程序中。
  • 成功返回读到的字符串str,失败或读到文件结尾时返回NULL。
#include <stdio.h>int main()
{FILE *pf;char str[100];pf = fopen(&#", "a");//以追加写模式打开,上面已经创建了该文件。fputc('I', pf);fclose(pf);pf = fopen(&#", "r");//以只读模式打开fgets(str, 12, pf);puts(str);fclose(pf);return 0;
}


④fputs

  • int fputs ( const char * str, FILE * stream );
  • 文本行输出函数,从程序中输出到文件中,向指定文件中写入字符串,适用于所有输出流。
  • 成功返回0,失败返回EOF。
#include <stdio.h>int main()
{FILE *pf;char str[100];pf = fopen(&#", "a");//以追加写模式打开,上面已经创建了该文件。fputs(" am sheena", pf);fclose(pf);pf = fopen(&#", "r");//以只读模式打开fgets(str, 22, pf);puts(str);fclose(pf);return 0;
}


⑤fprintf

  • int fprintf ( FILE * stream, const char * format, … );
  • 格式化输出函数,将数据写到文件中,适用于所有输出流。
  • 成功返回输出的字符数,失败返回一个负值。
  • 和printf用法差不多,只不过fprintf的使用时需要指定写入的文件指针。
#include <stdio.h>int main()
{FILE *pf;pf = fopen("mytest.c", "w");fputc('s', pf);fputs("nsheenan", pf);fprintf(pf,"语文:%dn数学:%dn英语:%dn", 98, 110, 99);fclose(pf);return 0;
}

⑥fscanf

  • int fscanf ( FILE * stream, const char * format, … );
  • 格式化输入函数,对应fprintf,将文件中的数据输入到程序中显示,适用于所有输入流。
  • 与fgets区别在于:fscanf遇到换行和空格时结束,而fgets遇到空格不会结束。
  • 成功返回输入到程序中的字符个数,失败返回EOF。
  • 与scanf一样使用,只不过加一个要读的文件的文件指针。
#include <stdio.h>int main()
{FILE *pf;int a, b, c;pf = fopen("mytest.c", "r");fscanf(pf,"语文:%dn数学:%dn英语:%dn", &a, &b, &c);printf("%d,%d,%dn", a, b, c);fclose(pf);return 0;
}


⑦fread

  • size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
  • 二进制输入,从一个文件中读数据,适用于文件。
  • 成功返回读取元素总数,失败或者读到文件末尾返回0。

⑧fwrite

  • size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
  • 二进制输出,将数据写入文件中,适用于文件。
  • 成功返回写入的元素的总数,失败返回0。
#include <stdio.h>
#include <string.h>
#include <assert.h>struct TelInfo
{char _name[24];char _tel[16];int _age;
};
char *my_itoa(int n, char* buf)
{assert(buf);int i = 0;while (n){buf[i] = n % 10 + '0';n /= 10;++i;}int begin = 0, end = i - 1;while (begin < end){char tmp = buf[end];buf[end] = buf[begin];buf[begin] = tmp;++begin;--end;}buf[i] = '';return buf;
}
int main()
{struct TelInfo info;strcpy(info._name, "sheena");strcpy(info._tel, "153****5645");info._age = 20;FILE *fp = fopen("telinfo.c", "wb");fwrite(&info, sizeof(info), 1, fp);fclose(fp);struct TelInfo other;FILE *fp2 = fopen("telinfo.c", "rb");fread(&other, sizeof(other), 1, fp2);fclose(fp2);printf("%s,%s,%dn", other._name, other._tel, other._age);return 0;
}

(2)数据文件的随机读写
①fseek

  • 根据文件指针的位置和偏移量来定位文件指针
  • int fseek ( FILE * stream, long int offset, int origin );
  • 成功返回0,失败返回非0。
//origin
不变	    参考位置
SEEK_SET	文件开始
SEEK_CUR	文件指针的当前位置
SEEK_END	文件结尾*
#include <stdio.h>int main()
{FILE *pf;pf = fopen("test.c", "wb");fputs("I am Sheena", pf);fseek(pf, 9, SEEK_SET);fputs("hello", pf);fclose(pf);return 0;
}


②ftell

  • 得到文件指针相对于起始位置的偏移量
  • long int ftell ( FILE * stream );
  • 成功返回当前位置的偏移量,失败返回-1L。
#include <stdio.h>
//获取一个文件的大小
int main()
{FILE *pf;pf = fopen("test.c", "r");fseek(pf, 0, SEEK_END);long int sz = ftell(pf);printf("%dn", sz);fclose(pf);return 0;
}


③rewind

  • 让文件指针的位置回到文件起始的位置。
  • void rewind ( FILE * stream );
  • 无返回值。
#include <stdio.h>int main()
{FILE *pf;pf = fopen("test12.c", "w");fputs("hello worldn", pf);rewind(pf);fputs("sheena:n", pf);fclose(pf);return 0;
}

7.文件结束符判定

  • 在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。而是应用于当文件读取结束时,判断是读取失败结束,还是读到文件末尾结束。
  • 文本文件:判断返回值是否为EOF(fgetc),NULL(fgets)
  • 二进制文件:判断返回值是否小于实际要读的个数。
#include <stdio.h>int main()
{FILE *pf;pf = fopen("test12.c", "r");int c;while ((c = fgetc(pf)) != EOF)putchar(c);if (ferror(pf))puts("error");else if (feof(pf))puts("end of the file");fclose(pf);return 0;
}

8.文件操作的总结

#include <stdio.h>
#include <string.h>
#include <assert.h>struct TelInfo
{char _name[24];char _tel[16];int _age;
};
char *my_itoa(int n, char* buf)
{assert(buf);int i = 0;while (n){buf[i] = n % 10 + '0';n /= 10;++i;}int begin = 0, end = i - 1;while (begin < end){char tmp = buf[end];buf[end] = buf[begin];buf[begin] = tmp;++begin;--end;}buf[i] = '';return buf;
}
int main()
{struct TelInfo info;strcpy(info._name, "sheena");strcpy(info._tel, "153****5645");info._age = 20;方法一:二进制读写法//FILE *fp = fopen("telinfo.c", "wb");//fwrite(&info, sizeof(info), 1, fp);//fclose(fp);//struct TelInfo other;//FILE *fp2 = fopen("telinfo.c", "rb");//fread(&other, sizeof(other), 1, fp2);//fclose(fp2);//printf("%s,%s,%dn", other._name, other._tel, other._age);//方法二:文本读写法1FILE *fpout = fopen("input.c", "w");fputs(info._name, fpout);fputc('n', fpout);fputs(info._tel, fpout);fputc('n', fpout);char age_buf[12];my_itoa(info._age, age_buf);fputs(age_buf, fpout);fputc('n', fpout);fclose(fpout);struct TelInfo other;FILE *fpin = fopen("input.c", "r");fscanf(fpin, "%sn%sn%dn", other._name, other._tel, &other._age);fclose(fpin);printf("%s,%s,%dn", other._name, other._tel, other._age);方法三:文本读写法2//FILE *fp = fopen("telinfo.c", "w");//fprintf(fp, "%sn%sn%dn", info._name, info._tel, info._age);//fclose(fp);////struct TelInfo other;//FILE *fpin = fopen("telinfo.c", "r");//fscanf(fpin, "%sn%sn%dn", other._name, other._tel, &other._age);//fclose(fpin);//printf("%s,%s,%dn", other._name, other._tel, other._age);return 0;
}

本文发布于:2024-02-01 18:07:33,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170678229038501.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:详解   语言   文件
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23