赞
踩
当我们在写程序的时候,有时候会给程序中添加一些数据,此时数据是存放在内存中的,可是在退出程序的时候,数据就消失了。
而加入文件的作用就是:可以将我们想要保存的数据直接保存到电脑硬盘上,并且我们可以自己进行删除和增加数据的操作,不会应为程序的关闭而丢失。
文件一般分为两种:1,程序文件 2,数据文件
程序文件一般指有指定格式,可以保存到操作系统中的文件,例如,Windows环境中的程序文件有:程序源文件(后缀为.c),目标文件(后缀为.obj),可执行程序(后缀为.exe)。
文件的内容不宜一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
我们知道,数组在内存中是连续的,我们想要调用这个数组的时候一般只需要记住这个数组的首地址就可以按照条件来依次访问数组中的内容。而C语言中的文件操作和对数组的操作非常相似,在C语言中,每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件相关的信息并保存在一个结构体变量中,该结构体来行是由系统声明的,命名为: FILE (需要用到头文件#include<stdio.h>)
因此,每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,因此,我们一般都是通过创建一个FILE的指针变量来维护这个FILE结构的变量,例:
FILE* pf;
这样我们就可以对一个文件信息区进行访问了;
文件操作一共有三个步骤: 打开文件->读文件/写文件->关闭文件。
只要打开文件,在使用完成后一定要有关闭文件的操作,可能会造成文件泄露或者降低程序运行效率和出现程序错误等。
打开文件和关闭文件的函数分别为:fopen fclose
注意:如果文件打开失败,fopen会返回一个空指针。
而文件的打开方式又有很多种:
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
“a”(追加) | 向文本文件尾添加数据 | 建立一个新的文件 |
“rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
“ab”(追加) | 向一个二进制文件尾添加数据 | 出错 |
“r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
“w+”(读写) | 为了读和写,建立一个新的文件 | 建立一个新的文件 |
“a+”(读写) | 为了读和写,在文件尾进行读写 | 建立一个新的文件 |
“rb+”(读写) | 为了读和写,打开一个二进制文件 | 出错 |
“wb+”(读写) | 为了读和写,建立一个新的二进制文件 | 建立一个新的文件 |
“ab+”(读写) | 打开一个二进制文件,在文件尾进行读写 | 建立一个新的文件 |
例:
#include<stdio.h> int main() { //打开文件 FILE* pf = fopen("test.txt", "w"); //以只写的方式打开/创建文本文件 if (pf == NULL) //判定是否打开成功,当打开文件失败时,fopen函数会返回空指针 { perror("fopen"); return 1; } // 写文件 //关闭文件 fclose(pf); pf = NULL; //用完指针后置空 return 0; }
功能 | 函数名 | 适用于 |
---|---|---|
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
注意:以上所讲的输入和输出是相对于内存来说的
下面我以fgetc举例,首先我们来看看fgetc函数的定义:
作用:
注意:fputc是一个字节一个字节的输入.
现在我用fputc来将26个小写英文字母输入到文件中:
#include<stdio.h> int main() { //打开文件 FILE* pf = fopen("test.txt", "w"); if (pf == NULL) { perror("fopen"); return 1; } //写文件 int i = 0; for (i = 0; i < 26; i++) { fputc('a'+i, pf); } //关闭文件 fclose(pf); pf = NULL; return 0; }
当程序运行结束后,我们打开当前目录下的test.txt文件:
下面我们用fgetc把刚才输出到文件中的26个字母全部读取出来
定义:
作用:
读取26个字母(注意,读取的时候一定要保证当前目录下是存在这个文件的,若文件不存在则会出错):
#include<stdio.h> int main() { FILE* pf = fopen("test.txt", "r"); // 读文本文件用 “r” if (pf == NULL) { perror("fopen"); return 1; } char ch = 0; //因为要读取字符,因此先创建一个临时变量 int i = 0; for (i = 0; i < 26; i++) { ch = fgetc(pf); // fgetc在读取一个字符后,内部文件位置指示器将前进到下一个字符 printf("%c ", ch); //将读取到的内容打印出来 } printf("\n"); fclose(pf); pf = NULL; return 0; }
程序运行结果为:
其他输入和输出函数是同样的道理,只是格式不同而已:
#include<stdio.h> int main() { FILE* pf = fopen("test.txt", "w"); // 以写的方式打开文件 if (pf == NULL) { perror("fopen"); return 1; } fputs("hello world", pf); // 向文件中输出字符串 fclose(pf); pf = NULL; return 0; }
运行结束后文件中的内容:
#include<stdio.h> int main() { FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { perror("fopen"); return 1; } char arr[20] = { 0 }; printf("%s \n", fgets(arr,12,pf)); //fgets会读取 12-1 个字节的数据 fclose(pf); pf = NULL; return 0; }
程序运行结果为:
#include<stdio.h> struct S { char name[20]; int age; }; int main() { struct S s = { "zhangsan",22 }; FILE* pf = fopen("test.txt", "w"); //以写的方式打开文件 if (pf == NULL) { perror("fopen"); return 1; } fprintf(pf,"%s %d \n", s.name, s.age); //将数据输出到文件中 fclose(pf); pf = NULL; return 0; }
运行结束后文件中的内容:
#include<stdio.h> struct S { char name[20]; int age; }; int main() { struct S s = {0}; FILE* pf = fopen("test.txt", "r"); //以读的方式打开文件 if (pf == NULL) { perror("fopen"); return 1; } fscanf(pf, "%s %d", &(s.name), &(s.age)); //将文件中的数据输入到内存中 printf("%s %d \n", s.name, s.age); //将内存中的数据输出到屏幕 fclose(pf); pf = NULL; return 0; }
程序运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。