这几天工作的过程中,常常要对TXT中的数据进行处理、分析。以前在学校时,对文件操作、文件内容处理的这部分知识用的不是很多,这几天用这些知识的时候,总是不太熟悉,要不停查阅资料。因此,这里总结一下,方便后期查阅。
在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O 文件操作,这里我们只介绍流式文件操作。
(1)FILE进行文件操作时,必须在程序一开始就先定义文件指针:FILE *指针类型变量。FILE 在 stdio.h 中定义如下:
- typedef struct
- {
- int level;
- unsigned flags;
- char fd;
- unsigned char hold;
- int bsize;
- unsigned char _FAR *buffer;
- unsigned char _FAR *curp;
- unsigned istemp;
- short token;
- } FILE;
- FILE *fopen(const char *filename,const char *mode);
"w"(只写) 为输出打开一个文本文件。若文件不存在,系统将用指定名建立一个新文件;若文件已经存在,则将从起始位置重新写,原有内容被更新
"rb"(只读) 为输入打开一个二进制文件。功能与"r"相同。
"wb"(只写) 为输出打开一个二进制文件。功能与"w"相同。
"a"(追加) 为追加数据打开一个文本文件。若文件不存在,系统将用指定名建立一个新文件;若文件已经存在,则新数据写在 原有内容之后 。
"ab"(追加) 为追加数据打开一个二进制文件。其余功能与"a"相同。
"r+"(读写) 为读/写打开一个已存在文本文件。既可读,也可写, 读写总是从文件的起始位置开始; 更换读写操作时不必关闭文件。
"rb+"(读写) 为读/写打开一个已存在的二进制文件。功能与"r+"相同。可由位置函数设置读写的起始位置。
"w+"(读写) 为读/写建立一个新的文本文件。 若文件已存在,原有内容将被更新。
"wb+"(读写) 为读/写建立一个新的二进制文件。功能与"w+"相同;可由位置函数设置读写起始位置。
"a+"(读写) 为读/写打开一个文本文件。功能与"a"相同, 只是在文件尾部添加新数据后,可以从头开始读。
"ab+"(读写) 为读/写打开一个二进制文件。功能与"a+"相同,只是在文件尾部添加新数据之后,可由位置 函数设置开始读的起始位置。
此函数返回一个FILE 指针,所以申明一个FILE 指针后不用初始化,而是用fopen()来返回一个指针并与一个特定的文件相连,如果成败,返回NULL。
- FILE *fp;
- if( fp=fopen("A.TXT","r") == NULL)
- {
- printf("can't find this file!/n");
- exit(0);
- }
- int fgetc(FILE *stream);
- char ch1=fgetc(fp);
(4)fgets
- char *fgets(char *buf, int bufsize, FILE *stream);
bufsize: 整型数据,指明buf指向的字符数组的大小。
*stream: 文件结构体指针,将要读取的文件流。
从文件结构体指针stream中读取数据, 每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'), 如果文件中的该行,不足bufsize个字符,则读完该行就结束。函数成功将返回buf,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。
例:如果一个文件的当前位置的文本如下:
Love, I Have
Since you can do it.
如果用fgets(str1,6,file1);去读取,则执行后str1 = "Love," ,读取了6-1=5个字符, 这个时候再执行fgets(str1,20,file1)则执行后str1 = " I Have\n"。 而如果fgets(str1,23,file1);
则执行str1="Love ,I Have",读取了一行(包括行尾的'\n',并自动加上字符串结束符'\0'),当前文件位置移至下一行, 虽然23大于当前行上字符总和,可是不会继续到下一行。而下一次调用fgets()继续读取的时候是从下一行开始读。
(5)fscanf
- int fscanf(FILE *stream, char *format,[argument...]);
从一个流、文件(stream)中读入数据,执行格式化输入,然后将结果按照格式保存在列表中(可以理解为: 将TXT文件中的内容,有针对性地提取出来,并保存在特定的 列表、数组中),fscanf遇到空格和换行时结束,注意空格时也结束。这与fgets有区别,fgets遇到空格不结束。
- FILE *fp = 0;
- char tmp[255] = {0};
- fp = fopen(argv[1],"r+");
- while(EOF != fscanf(fp,"%*[^','],\"%*[^','],%[^','],%*s",tmp))
- {
- sscanf(tmp,"\"%s\"",tmp1);
- printf("%d\n",atoi(tmp1));
- }
- int fprintf(FILE *stream,char *format,[argument]);
- char s[] = "this is a string";
- char c = '\n';
- stream = fopen( "fprintf.out", "w" );
- fprintf( stream, "%s%c", s, c );
- fprintf( stream, "%d\n", i );
- fprintf( stream, "%f\n", fp );
(7)fwrite
- size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
- FILE *stream;
- struct mystruct s;
- if ((stream = fopen("TEST.$$$", "wb")) == NULL) /* open file TEST.$$$ */
- {
- fprintf(stderr, "Cannot open output file.\n");
- return 1;
- }
- s.i = 0;
- s.cha = 'A';
- fwrite(&s, sizeof(s), 1, stream); /* 写的struct文件*/
- int sscanf(const char *buffer,const char *format,[argument ]...);
- sscanf("123456abcdedfBCDEF","%[1-9A-Z]",buf);
- sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
- printf("%s\n", buf);
- ssize_t getline(char **lineptr, size_t *n, FILE *stream);
- FILE *fp;
- char *line = NULL;
- size_t len = 0;
- ssize_t read;
- if(!(fp=fopen("1.txt","r")))
- {
- printf("\nerror on open 1.txt file!\n");
- exit(1);
- }
- while ((read = getline(&line, &len, fp)) != -1);