C语言文件操作——打开 关闭 顺序读写 随机读写
创始人
2024-04-13 08:54:53
0

1.文件的打开和关闭

1.1 文件指针

在打开一个文件的时候,会创建一个文件信息区,而文件指针指向的内容就是文件信息区。

文件信息区中存储的到底是什么内容的,我们可以在VS2013中查看一下文件信息区的内容(不同编译器下有所差异)。

struct _iobuf {char* _ptr;int _cnt;char* _base;int _flag;int _file;int _charbuf;int _bufsiz;char* _tmpfname;
};
typedef struct _iobuf FILE;

文件指针pf的类型是FILE*:

FILE* pf;//文件指针

1.2 文件的打开和关闭 

文件的打开和关闭我们都知道怎么操作,但是如果在编程语言中提到打开关闭文件,我们可能就一无所知了。

下面介绍两个函数:

//打开文件的函数fopen
FILE * fopen ( const char * filename, const char * mode );
//关闭文件的函数fclose
int fclose ( FILE * stream );

fopen中有一个参数mode,这个参数其实对应的是打开方式;打开文件有很多种方式,比较常用的只有三种:

文件使用方式含义如果指定的文件不存在
r(只读)读取一个已经存在的文本文件出错
w(只写)打开一个文本文件,输出数据,打开文件之前会先清空文件内容建立新文件
a (追加)向文本文件末尾添加数据,原来文件中的数据保留,新的数据添加到文件为,原文件EOF保留建立新文件

 演示fopen和fclose的使用:

int main()
{//打开文件FILE* pf = fopen("test.txt", "w");//关闭文件fclose(pf);pf = NULL;return 0;
}

2.文件的顺序读写

打开文件的目的是对文件进行读写,四个常用的文件读写函数:

功能函数名适用于
字符输入函数fgetc所有输入流
字符输出函数fputc所有输出流
文本行输入函数fgets所有输入流
文本行输出函数fputs所有输出流

2.1 fputc 

int fputc( int c, FILE *stream );//Writes a character to a stream (fputc, fputwc) or to stdout (_fputchar, _fputwchar).

fopen创建的文件默认在当前路径下;

void test_fputc()
{FILE* pf = fopen("test.txt", "w");//fputc的使用 两个参数-第一个为输出到文件的字符,第二个为输出的文件流for (int ch = 'a'; ch <= 'z'; ch++){fputc(ch, pf);//输出26个英文字母}fclose(pf);
}

fputc每次只能输出单个字符,想要输出多个字符需要借助循环。 

 

  

2.2 fgetc

int fgetc( FILE *stream );

fputc是把字符输出到文件,fgetc则是把文件中的内容读出来;从用法上来说fgetc的使用更加简单。

void test_fgetc()
{FILE* pf = fopen("test.txt", "r");//读取test.txt中的内容//使用fgetc读数据char ch;while((ch = fgetc(pf)) != EOF){printf("%c ", ch);}fclose(pf);
}

使用fgetc也是可以读取成功的,而且每次读取之后文件指针也是会向后移动的。 

2.3 fputs

单个字符的输入和输出会很麻烦,那么可不可以以字符串的形式输出和输入呢?

答案是可以的,那就是使用fputs和fgets。

int fputs( const char *string, FILE *stream );

fputs在使用上还是很简单的:

void test_fputs()
{FILE* pf = fopen("mytest.txt", "w");//使用fputs将字符输出到文件中 两个参数-第一个为常量字符串,第二个为输出的文件流指针fputs("this is a test\n", pf);fclose(pf);
}

  

2.4 fgets

fgets和fputs作用相反,fgets用来读取文件中的数据到程序中:

char *fgets( char *string, int n, FILE *stream );
//fgets有三个参数,string为读取到的内存区域,n表示读取的最大字符个数,stream为文件指针
void test_fgets()
{FILE* pf = fopen("mytest.txt", "r");//读数据//fgets char buf[101] = { 0 };printf("%s\n", fgets(buf, 101, pf));fclose(pf);
}

3.两组函数的对比

3.1 scanf &fscanf &sscanf

函数的参数:

scanf:  int scanf( const char *format [,argument]... );

fscanf:  int fscanf( FILE *stream, const char *format [, argument ]... );

sscanf:  int sscanf( const char *buffer, const char *format [, argument ] ... );

针对的输入流:

scanf  :格式化的输入函数

fscanf :所有输入流

sscanf:把一个字符串转换成格式化的数据

 sscanf使用示例:

struct S
{char name[20];int age;double grade;
};int main()
{char buf[256] = { 0 };struct S tmp = { 0 };struct S s = { "zhangsan", 50, 50.8 };sprintf(buf, "%s %d %lf", s.name, s.age, s.grade);//把结构体中的数据转化为字符串//从buf中提取一个结构体对象sscanf(buf, "%s %d %lf", tmp.name, &(tmp.age), &(tmp.grade));printf("%s %d %f", tmp.name, tmp.age, tmp.grade);return 0;
}

3.2 printf &fprintf & sprintf

函数参数:

printf:  int printf( const char *format [, argument]... );

fprintf:  int fprintf( FILE *stream, const char *format [, argument ]...);

sprintf:  int sprintf( char *buffer, const char *format [, argument] ... );

针对的输出流:

printf   : 格式化的输出函数

fprintf  : 针对所有输出流的格式化输出函数

sprintf : 把一个格式化的数据转化成字符串

 fprintf使用示例:

struct S
{char name[20];int age;double grade;
};int main()
{struct S s = { "张三", 50, 50.8 };FILE* pf = fopen("test.txt", "w");fprintf(pf, "%s %d %lf", s.name, s.age, s.grade);fclose(pf);pf = NULL;return 0;
}

sprintf使用示例:

struct S
{char name[20];int age;double grade;
};int main()
{char buf[256] = { 0 };struct S s = { "zhangsan", 50, 50.8 };sprintf(buf, "%s %d %lf", s.name, s.age, s.grade);printf("%s\n", buf);return 0;
}

4.文件的随机读写

4.1 fseek

int fseek( FILE *stream, long offset, int origin );

fseek是根据文件指针的偏移量来进行随机读写。

origin的三种情况:

SEEK_CUR:文件指针的当前位置

SEEK_END:文件结束位置

SEEK_SET:文件开始位置

若origin使用SEEK_CUR,offset不能为负数;若origin使用SEEK_END,offset不能为正。

void test_fseek()
{FILE* pFile = fopen("example.txt", "w");//写文件fputs("This is an apple.", pFile);//偏移fseek(pFile, 9, SEEK_SET);//关闭文件fputs(" sam", pFile);fclose(pFile);pFile = NULL;
}

 

下面解释一下为什么是这个结果:

 

4.2 ftell

返回文件指针相对于起始位置的偏移量,返回类型为long。

long int ftell ( FILE * stream );

示例:

void test_ftell()
{//打开文件FILE* pf = fopen("test.txt", "w");//随机读fputc('a', pf);fputc('b', pf);long pos = ftell(pf);printf("%d\n", pos);//关闭文件fclose(pf);pf = NULL;
}

 4.3 rewind

让文件指针的位置回到文件的起始位置。

void rewind ( FILE * stream );

示例:

int main()
{FILE* pf = fopen("test.txt", "w");fputc('a', pf);fputc('b', pf);long pos = ftell(pf);//2printf("%d\n", pos);rewind(pf);pos = ftell(pf);printf("%ld", pos);//回到起始位置0fclose(pf);pf = NULL;return 0;
}

总结:文件操作的内容和之前的基础内容相比还是有难度的,主要是一些不常见的函数需要学习使用;然后文件操作部分的代码还是需要自己手动去敲的,不然一段时间之后,再回顾这些内容的时候就会发现已经忘得七七八八了;最后有时间的话可以总结成博客,在复习的时候借助自己的博客是更高效的。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...