1.文件指针
缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名FILE。
例如,VS2013编译环境提供的 stdio.h 头文件中有以下的文件类型申明
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
下面我们可以创建一个FILE*的指针变量:
FILE* pf; //文件指针变量
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。

打算读写一个文件的时候
- 打开文件
- 被打开的文件就维护了一个文件信息区
2. 文件的打开和关闭
文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。
//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream )
文件的打开方式
| 文件使用方式 | 含义 | 如果指定文件不存在 |
| “r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
| “w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
| “a”(追加) | 向文本文件尾添加数据 | 建立一个新的文件 |
| “rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
| “wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
| “ab”(追加) | 向一个二进制文件尾添加数据 | 建立一个新的文件 |
| “r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
| “w+”(读写) | 为了读和写,建议一个新的文件 | 建立一个新的文件 |
| “a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
| “rb+”(读写) | 为了读和写打开一个二进制文件 | 出错 |
| “wb+”(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
| “ab+”(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
例子:
#include <stdio.h>
int main ()
{
FILE * pFile;
//打开文件
pFile = fopen ("myfile.txt","w");
//文件操作
if (pFile!=NULL)
{
fputs ("fopen example",pFile);
//关闭文件
fclose (pFile);
}
return 0;
}
对此我们可以将文件的操作分为三大块:1、打开文件。2、对文件操作。3、关闭文件。
3.文件的顺序读写
| 功能 | 函数名 | 适用于 |
| 字符输入函数 | fgetc | 所有输入流 |
| 字符输出函数 | fputc | 所有输出流 |
| 文本行输入函数 | fgets | 所有输入流 |
| 文本行输出函数 | fputs | 所有输出流 |
| 格式化输入函数 | fscanf | 所有输入流 |
| 格式化输出函数 | fprintf | 所有输出流 |
| 二进制输入 | fread | 文件 |
| 二进制输出 | fwrite | 文件 |
这个流其实是传输数据的通道。它能传输数据将数据从别的地方,如内存,文件等地方传输给程序或将程序中的数据传输到别的地方。
3.1 fgetc函数
它的作用是从流中获取字符。
可以看到出错了,以为我们是用"r"来打开文件,而"r"如果指定的文件不存在则会出错。

我们只需要自己创建一个data文件即可。
3.2 fputc函数
它的作用是将字符写入流。
#include <stdio.h>
int main()
{
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int i = 0;
for (i = 0; i < 26; i++)
{
fputc('a'+i, stdout);
}
fclose(pf);
pf = NULL;
return 0;
}

3.3 fgets函数
它的作用是从流中获取字符串。
#include <stdio.h>
int main()
{
FILE* pf = fopen("data.txt", "r");
if (NULL == pf)
{
perror("fopen");
return 1;
}
char arr[10] = { 0 };
fgets(arr, 10, pf);
printf("%s", arr);
fclose(pf);
pf = NULL;
return 0;
}
因为我们是用"r"来打开文件,所以需要先在文件中输入字符串。


3.4 fputs函数
它的作用是将字符串写入流。
int main()
{
FILE* pf = fopen("data.txt", "w");
if (NULL == pf)
{
perror("fopen");
return 1;
}
fputs("hello world\n", pf);
fputs("world hello\n", pf);
fclose(pf);
pf = NULL;
return 0;
}

3.5 fprintf函数
可以看到fprintf,和printf只有一点点不一样

#include <stdio.h>
struct S
{
int a;
float s;
};
int main()
{
FILE* pf = fopen("data.txt", "w");
if (NULL == pf)
{
perror("fopen");
return 1;
}
struct S s = { 100, 3.14f };
fprintf(pf, "%d %f", s.a, s.s);
fclose(pf);
pf = NULL;
return 0;
}

3.6 fscanf函数

#include <stdio.h>
struct S
{
int a;
float s;
};
int main()
{
FILE* pf = fopen("data.txt", "r");
if (NULL == pf)
{
perror("fopen");
return 1;
}
struct S s = {0};
fscanf(pf, "%d %f", &(s.a), &(s.s));
fprintf(stdout, "%d %f", s.a, s.s);
fclose(pf);
pf = NULL;
return 0;
}
我们在刚刚的使用fprintf函数的时候,已经让记事本有了字符,
所以在这里使用fscanf时读取的还是刚刚的字符。

本文介绍了C语言中文件指针的概念,如何使用fopen、fclose等函数进行文件的打开、关闭以及顺序读写,包括fgetc、fputc、fgets、fputs、fprintf和fscanf等函数的应用实例。

3823

被折叠的 条评论
为什么被折叠?



