Error[8]: Undefined offset: 659, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

C语言 文件


一、文件 1.1 什么是文件

 磁盘文件在DOS管理中被定义为存贮在外部介质上的程序或数据的集合,是一批逻辑上有联系的数据。


每个文件都有个文件名作为标识,每个文件在磁盘中的具体存放位置、格式都由 *** 作系统中的文件系统管理,也就是说, *** 作系统是以文件为单位对程序或数据进行管理的。



 在C语言中文件的含义更为广泛,不仅包含以上所述的磁盘文件,还包括一切能进行输入/输出的终端设备,它们被看成是设备文件。


如键盘常称为标准输入文件,显示器称为标准输出文件。


即在C语言中文件是由磁盘文件和设备文件组成的,磁盘文件根据功能又分为程序文件和数据文件

1.2 文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用,文件名包含3部分:文件路径+文件名主干+文件后缀
例如Windows下: c:\code\test.txt
Linux下: /tmp/file.txt (Linux系统不识别文件后缀名,后缀名是给用户看的)


二、 文件流的打开与关闭 2.1 流

流是一个高度抽象概念
 当前计算机具有大量不同设备,很多与I/O *** 作有关。


如:软盘、硬盘、通信端口、视屏适配器等。


每种设备具有不同的特性和 *** 作协议, *** 作系统负责与这些不同设备的I/O细节,并向程序员提供一个更为简单和统一的I/O接口
 C语言进一步对I/O接口进行抽象引入流的概念。


根据流的方向分为输入流和输出流。


程序要输入数据只需从输入流中读入;输出数据只需向输出流中写即可。


特定I/O设备的细节对程序员是隐藏的。


说明:每个C语言程序运行时默认打开3个流,分别为标准输入流(stdin)、标准输出流(stdout)、标准错误流(stderr)。


标准输入默认是键盘,标准输出默认是显示器

2.2 文件指针类型(FILE *)

每个被使用的文件都会在内存中开辟了一个对应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。


这些信息是保存在一个结构体变量中的。


该结构体类型是FILE类型,在中定义,我们也将这个结构体变量称为文件流

//VS2013 IDE中头文件对FILE的定义
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 * 的指针来维护这个FILE类型结构体变量,所以FILE * 指针指向一个文件流

FILE* pf;//文件指针变量

pf是一个指向FILE类型数据的指针变量。


可以使pf指向某个文件的文件信息区(是一个结构体变量),通过该文件信息区中的信息就能够访问该文件

2.3 文件流的打开和关闭

fopen函数功能:
打开一个指定文件,并返回一个指向该文件流(文件信息区)的FILE * 指针

库函数fopen函数声明
FILE * fopen ( const char * filename, const char * mode );
返回值:打开文件成功返回指向该文件流(文件信息区)的FILE * 指针,打开失败返回NULL指针,所以应该检查fopen函数的返回值
filename :需打开文件或设备名字,可以是绝对路径或相对路径写法
mode:文件打开模式

常用模式说明:
r :以只读方式打开文件,该文件必须存在
w :以只写方式打开文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。



a :以追加的方式打开只写文件。


若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件末尾
b :打开二进制文件,配合上面r、w、a使用

fclose函数功能:
刷新文件缓冲区,关闭一个指定文件(释放文件流)

库函数fclose函数声明
int fclose ( FILE * stream );
返回值:关闭成功返回0,失败返回EOF
stream:指向文件流的指针

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //以只读方式打开一个文件file.txt
	if (NULL == pf) //打开失败
	{
		perror("fopen"); //打印错误信息
		return -1; //退出程序
	}
	//读 *** 作
	fclose(pf); //关闭文件
	pf = NULL;
	return 0;
}

三、 顺序读写

顺序读写:对文件的输入和输出只能按照顺序读写

3.1 字符函数 3.1.1 字符输入 fgetc函数

fgetc函数功能:
返回指定流的位置指示器指向的字符,然后位置指示器向前移动一个字符,简单理解就是从指定流读取1个字符

库函数fgetc函数声明
int fgetc ( FILE * stream );
返回值:读取成功返回对应字符的ascii码值。


读取到文件结束标志时,则函数返回EOF并设置流的文件结束指示符(feof)。


如果发生读错误,该函数返回EOF并设置流的错误指示符(ferror)
stream:指向输入流(文件流、标准输入流)的指针

测试1:从文件中读取字符

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //file.txt存在,内容为hello
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	printf("%c\n", fgetc(pf)); //输出读取第1个字符
	printf("%c\n", fgetc(pf)); //输出读取第2个字符
	fclose(pf);
	pf = NULL;
	return 0;
}

输出

h
e

测试2:从标准输入中读取字符

#include 
int main()
{
	char c = fgetc(stdin);
	printf("%c\n", c);
	return 0;
}

输入

a

输出

a
3.1.2 字符输出 fputc函数

fputc函数功能:
将一个字符写入流并使位置指示器向前移动,即字符被写入到流的内部位置指示器所指示的位置,然后该位置指示器自动前进1,简单理解就是写1个字符到流中

库函数fputc函数声明
int fputc ( int character, FILE * stream );
返回值:如果成功,则返回所写的字符。


如果发生写错误,则返回EOF并设置错误指示器(ferror)。



character :待写入字符
stream:指向输出流(文件流、标准输出流)的指针

测试1:输出字符到文件

#include 
int main()
{
//将字符'a'  'b'  'c' 写入到文件
	FILE* pf = fopen("file.txt", "w");
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

测试2:输出字符到标准输出

#include 
int main()
{
	int c = fputc('h', stdout);
	c = fputc('e', stdout);
	c = fputc('l', stdout);
	return 0;
}

屏幕上显示

hel
3.2 未格式化文本行函数 3.2.1 未格式化文本行输入 pgets函数

fgets函数功能:
从流中读取num-1个字符到字符数组str中,或者遇到换行符或文件结束符停止(以最先发生的为准)。


换行符会使fgets停止读取,但函数会认为它是一个有效的字符,并添加’\0’使成为一个字符串

库函数fgetc函数声明
char * fgets ( char * str, int num, FILE * stream );;
返回值:读取成功,函数返回str。


如果在读取中时遇到文件结束符,则设置eof指示器(feof),返回一个空指针(str的内容保持不变)。



如果发生读错误,则设置错误指示符(ferror)并返回一个空指针 (但str所指向的内容可能已经改变)
str :字符数组的数组名
num:最多复制num个字符到str数组
stream:指向输入流(文件流、标准输入流)的指针

测试1:从文件中读取未格式文本行

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //文件file.txt内容为:Hello World
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	char arr[20] = "#################";
	fgets(arr, 5, pf); //读取5-1个字符到arr数组,并添加'printf'到数组,即"Hell"
	("%s",) arr;//打印Hell fgets
	(,arr5 ,) pf;读取5-1个字符到arr数组,并添加'printf'到数组,即"o Wo" (
	"%s",); arr//打印o Wofclose (
	);pf=NULL
	pf ; return0
	; }Hello Wo

#

输出

include

测试2:从标准输入中读取未格式化文本行

intmain 
( )char[
{
	] arr="##########" ; fgets(
	,6arr, stdin) ;printf(
	"%s\n",); arrreturn0
	; }abcdef

abcde

输入

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

输出

#
3.2.2 未格式化文本行输出 fputs函数

fputs函数功能:
将str指向的字符串写入流。


函数从指定的地址(str)开始复制,遇到’\0’停止。


'\0’不会复制到流中

库函数fputs函数声明
include
返回值:如果成功,将返回一个非负值。


在出错时,函数返回EOF并设置错误指示符(ferror)
str :需写入的字符串起始地址
stream:指向输出流(文件流、标准输出流)的指针

测试1 :输出未格式化文本行到文件

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","w") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }fputs
	(
	"Hello World",); pffputs(
	"Hello WuHan",); pffclose(
	);pf=NULL
	pf ; return0
	; }Hello WorldHello WuHan

#

打开file.txt文件发现内容为:

include

所以当要写入多行时需要在字符串中加入换行符,即 fputs(“Hello World\n”, pf);

测试2 :输出未格式化文本行到标准输出

intmain 
( )char[
{
	] arr1="Hello World\n" ; fputs(
	,stdoutarr1) ;fputs(
	"Hello Wuhan\n",stdout) ;return0
	; }Hello World
Hello Wuhan

long int ftell ( FILE * stream );;

屏幕上显示

#

四、随机读写

随机读写:以任意顺序读写文件的不同位置,文件的读写位置是由文件信息区(文件流)中位置指示器决定

4.1 获取文件当前位置 ftell函数

ftell函数功能:
返回流的位置指示器的当前值(文件当前位置)

库函数ftell声明
include
返回值:对于二进制流,这是当前位置距离文件起始位置之间字节数。


对于文本流,数值可能没有意义(因为不同系统换行符不一样,如:windwos换行符为\r\n  linux换行符为\n)。


失败返回-1L
stream:指向流的指针

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","r") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }long
	=
	ftell position ( );pf//获取文件当前位置printf (
	"文件当前位置:%d\n",); positionfgetc(
	);pf//读取位置指示器的字符,读完后位置指示器向前移动= ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionfclose(
	);pf=NULL
	pf ; return0
	; }0
1

输出

文件当前位置:void rewind ( FILE * stream );
文件当前位置:void rewind ( FILE * stream );
4.2 改变文件当前位置 fseek函数

fseek函数功能:
将流的位置指示器(当前位置)设置为指定位置,成功调用该函数后,清除流的文件结束符和错误内部指示符

库函数ftell声明
#
stream:指向流的指针

4.3 设置文件当前位置为起始位置 rewind函数

rewind函数功能:
将流的位置指示器(当前位置)设置为文件的起始位置,成功调用该函数后,清除流的文件结束符和错误内部指示符

库函数ftell声明
include
stream:指向流的指针

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","r") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }long
	=
	ftell position ( );pf//获取文件当前位置printf (
	"文件当前位置:%d\n",); positionfseek(
	,3pf, SEEK_SET) ;=ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionrewind(
	);pf=ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionfclose(
	);pf=NULL
	pf ; return0
	; }[+++]
[+++]
)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 660, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

C语言 文件


一、文件 1.1 什么是文件

 磁盘文件在DOS管理中被定义为存贮在外部介质上的程序或数据的集合,是一批逻辑上有联系的数据。


每个文件都有个文件名作为标识,每个文件在磁盘中的具体存放位置、格式都由 *** 作系统中的文件系统管理,也就是说, *** 作系统是以文件为单位对程序或数据进行管理的。



 在C语言中文件的含义更为广泛,不仅包含以上所述的磁盘文件,还包括一切能进行输入/输出的终端设备,它们被看成是设备文件。


如键盘常称为标准输入文件,显示器称为标准输出文件。


即在C语言中文件是由磁盘文件和设备文件组成的,磁盘文件根据功能又分为程序文件和数据文件

1.2 文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用,文件名包含3部分:文件路径+文件名主干+文件后缀
例如Windows下: c:\code\test.txt
Linux下: /tmp/file.txt (Linux系统不识别文件后缀名,后缀名是给用户看的)


二、 文件流的打开与关闭 2.1 流

流是一个高度抽象概念
 当前计算机具有大量不同设备,很多与I/O *** 作有关。


如:软盘、硬盘、通信端口、视屏适配器等。


每种设备具有不同的特性和 *** 作协议, *** 作系统负责与这些不同设备的I/O细节,并向程序员提供一个更为简单和统一的I/O接口
 C语言进一步对I/O接口进行抽象引入流的概念。


根据流的方向分为输入流和输出流。


程序要输入数据只需从输入流中读入;输出数据只需向输出流中写即可。


特定I/O设备的细节对程序员是隐藏的。


说明:每个C语言程序运行时默认打开3个流,分别为标准输入流(stdin)、标准输出流(stdout)、标准错误流(stderr)。


标准输入默认是键盘,标准输出默认是显示器

2.2 文件指针类型(FILE *)

每个被使用的文件都会在内存中开辟了一个对应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。


这些信息是保存在一个结构体变量中的。


该结构体类型是FILE类型,在中定义,我们也将这个结构体变量称为文件流

//VS2013 IDE中头文件对FILE的定义
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 * 的指针来维护这个FILE类型结构体变量,所以FILE * 指针指向一个文件流

FILE* pf;//文件指针变量

pf是一个指向FILE类型数据的指针变量。


可以使pf指向某个文件的文件信息区(是一个结构体变量),通过该文件信息区中的信息就能够访问该文件

2.3 文件流的打开和关闭

fopen函数功能:
打开一个指定文件,并返回一个指向该文件流(文件信息区)的FILE * 指针

库函数fopen函数声明
FILE * fopen ( const char * filename, const char * mode );
返回值:打开文件成功返回指向该文件流(文件信息区)的FILE * 指针,打开失败返回NULL指针,所以应该检查fopen函数的返回值
filename :需打开文件或设备名字,可以是绝对路径或相对路径写法
mode:文件打开模式

常用模式说明:
r :以只读方式打开文件,该文件必须存在
w :以只写方式打开文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。



a :以追加的方式打开只写文件。


若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件末尾
b :打开二进制文件,配合上面r、w、a使用

fclose函数功能:
刷新文件缓冲区,关闭一个指定文件(释放文件流)

库函数fclose函数声明
int fclose ( FILE * stream );
返回值:关闭成功返回0,失败返回EOF
stream:指向文件流的指针

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //以只读方式打开一个文件file.txt
	if (NULL == pf) //打开失败
	{
		perror("fopen"); //打印错误信息
		return -1; //退出程序
	}
	//读 *** 作
	fclose(pf); //关闭文件
	pf = NULL;
	return 0;
}

三、 顺序读写

顺序读写:对文件的输入和输出只能按照顺序读写

3.1 字符函数 3.1.1 字符输入 fgetc函数

fgetc函数功能:
返回指定流的位置指示器指向的字符,然后位置指示器向前移动一个字符,简单理解就是从指定流读取1个字符

库函数fgetc函数声明
int fgetc ( FILE * stream );
返回值:读取成功返回对应字符的ascii码值。


读取到文件结束标志时,则函数返回EOF并设置流的文件结束指示符(feof)。


如果发生读错误,该函数返回EOF并设置流的错误指示符(ferror)
stream:指向输入流(文件流、标准输入流)的指针

测试1:从文件中读取字符

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //file.txt存在,内容为hello
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	printf("%c\n", fgetc(pf)); //输出读取第1个字符
	printf("%c\n", fgetc(pf)); //输出读取第2个字符
	fclose(pf);
	pf = NULL;
	return 0;
}

输出

h
e

测试2:从标准输入中读取字符

#include 
int main()
{
	char c = fgetc(stdin);
	printf("%c\n", c);
	return 0;
}

输入

a

输出

a
3.1.2 字符输出 fputc函数

fputc函数功能:
将一个字符写入流并使位置指示器向前移动,即字符被写入到流的内部位置指示器所指示的位置,然后该位置指示器自动前进1,简单理解就是写1个字符到流中

库函数fputc函数声明
int fputc ( int character, FILE * stream );
返回值:如果成功,则返回所写的字符。


如果发生写错误,则返回EOF并设置错误指示器(ferror)。



character :待写入字符
stream:指向输出流(文件流、标准输出流)的指针

测试1:输出字符到文件

#include 
int main()
{
//将字符'a'  'b'  'c' 写入到文件
	FILE* pf = fopen("file.txt", "w");
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

测试2:输出字符到标准输出

#include 
int main()
{
	int c = fputc('h', stdout);
	c = fputc('e', stdout);
	c = fputc('l', stdout);
	return 0;
}

屏幕上显示

hel
3.2 未格式化文本行函数 3.2.1 未格式化文本行输入 pgets函数

fgets函数功能:
从流中读取num-1个字符到字符数组str中,或者遇到换行符或文件结束符停止(以最先发生的为准)。


换行符会使fgets停止读取,但函数会认为它是一个有效的字符,并添加’\0’使成为一个字符串

库函数fgetc函数声明
char * fgets ( char * str, int num, FILE * stream );;
返回值:读取成功,函数返回str。


如果在读取中时遇到文件结束符,则设置eof指示器(feof),返回一个空指针(str的内容保持不变)。



如果发生读错误,则设置错误指示符(ferror)并返回一个空指针 (但str所指向的内容可能已经改变)
str :字符数组的数组名
num:最多复制num个字符到str数组
stream:指向输入流(文件流、标准输入流)的指针

测试1:从文件中读取未格式文本行

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //文件file.txt内容为:Hello World
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	char arr[20] = "#################";
	fgets(arr, 5, pf); //读取5-1个字符到arr数组,并添加'printf'到数组,即"Hell"
	("%s",) arr;//打印Hell fgets
	(,arr5 ,) pf;读取5-1个字符到arr数组,并添加'printf'到数组,即"o Wo" (
	"%s",); arr//打印o Wofclose (
	);pf=NULL
	pf ; return0
	; }Hello Wo

#

输出

include

测试2:从标准输入中读取未格式化文本行

intmain 
( )char[
{
	] arr="##########" ; fgets(
	,6arr, stdin) ;printf(
	"%s\n",); arrreturn0
	; }abcdef

abcde

输入

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

输出

#
3.2.2 未格式化文本行输出 fputs函数

fputs函数功能:
将str指向的字符串写入流。


函数从指定的地址(str)开始复制,遇到’\0’停止。


'\0’不会复制到流中

库函数fputs函数声明
include
返回值:如果成功,将返回一个非负值。


在出错时,函数返回EOF并设置错误指示符(ferror)
str :需写入的字符串起始地址
stream:指向输出流(文件流、标准输出流)的指针

测试1 :输出未格式化文本行到文件

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","w") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }fputs
	(
	"Hello World",); pffputs(
	"Hello WuHan",); pffclose(
	);pf=NULL
	pf ; return0
	; }Hello WorldHello WuHan

#

打开file.txt文件发现内容为:

include

所以当要写入多行时需要在字符串中加入换行符,即 fputs(“Hello World\n”, pf);

测试2 :输出未格式化文本行到标准输出

intmain 
( )char[
{
	] arr1="Hello World\n" ; fputs(
	,stdoutarr1) ;fputs(
	"Hello Wuhan\n",stdout) ;return0
	; }Hello World
Hello Wuhan

long int ftell ( FILE * stream );;

屏幕上显示

#

四、随机读写

随机读写:以任意顺序读写文件的不同位置,文件的读写位置是由文件信息区(文件流)中位置指示器决定

4.1 获取文件当前位置 ftell函数

ftell函数功能:
返回流的位置指示器的当前值(文件当前位置)

库函数ftell声明
include
返回值:对于二进制流,这是当前位置距离文件起始位置之间字节数。


对于文本流,数值可能没有意义(因为不同系统换行符不一样,如:windwos换行符为\r\n  linux换行符为\n)。


失败返回-1L
stream:指向流的指针

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","r") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }long
	=
	ftell position ( );pf//获取文件当前位置printf (
	"文件当前位置:%d\n",); positionfgetc(
	);pf//读取位置指示器的字符,读完后位置指示器向前移动= ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionfclose(
	);pf=NULL
	pf ; return0
	; }0
1

输出

文件当前位置:void rewind ( FILE * stream );
文件当前位置:void rewind ( FILE * stream );
4.2 改变文件当前位置 fseek函数

fseek函数功能:
将流的位置指示器(当前位置)设置为指定位置,成功调用该函数后,清除流的文件结束符和错误内部指示符

库函数ftell声明
#
stream:指向流的指针

4.3 设置文件当前位置为起始位置 rewind函数

rewind函数功能:
将流的位置指示器(当前位置)设置为文件的起始位置,成功调用该函数后,清除流的文件结束符和错误内部指示符

库函数ftell声明
include
stream:指向流的指针

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","r") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }long
	=
	ftell position ( );pf//获取文件当前位置printf (
	"文件当前位置:%d\n",); positionfseek(
	,3pf, SEEK_SET) ;=ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionrewind(
	);pf=ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionfclose(
	);pf=NULL
	pf ; return0
	; }
[+++]
)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
C语言 文件_C_内存溢出

C语言 文件

C语言 文件,第1张

C语言 文件

  • 一、文件

    • 1.1 什么是文件
    • 1.2 文件名

  • 二、 文件流的打开与关闭

    • 2.1 流
    • 2.2 文件指针类型(FILE *)
    • 2.3 文件流的打开和关闭

  • 三、 顺序读写

    • 3.1 字符函数
      • 3.1.1 字符输入 fgetc函数
      • 3.1.2 字符输出 fputc函数
    • 3.2 未格式化文本行函数
      • 3.2.1 未格式化文本行输入 pgets函数
      • 3.2.2 未格式化文本行输出 fputs函数

  • 四、随机读写

    • 4.1 获取文件当前位置 ftell函数
    • 4.2 改变文件当前位置 fseek函数
    • 4.3 设置文件当前位置为起始位置 rewind函数


一、文件 1.1 什么是文件

 磁盘文件在DOS管理中被定义为存贮在外部介质上的程序或数据的集合,是一批逻辑上有联系的数据。


每个文件都有个文件名作为标识,每个文件在磁盘中的具体存放位置、格式都由 *** 作系统中的文件系统管理,也就是说, *** 作系统是以文件为单位对程序或数据进行管理的。



 在C语言中文件的含义更为广泛,不仅包含以上所述的磁盘文件,还包括一切能进行输入/输出的终端设备,它们被看成是设备文件。


如键盘常称为标准输入文件,显示器称为标准输出文件。


即在C语言中文件是由磁盘文件和设备文件组成的,磁盘文件根据功能又分为程序文件和数据文件

1.2 文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用,文件名包含3部分:文件路径+文件名主干+文件后缀
例如Windows下: c:\code\test.txt
Linux下: /tmp/file.txt (Linux系统不识别文件后缀名,后缀名是给用户看的)


二、 文件流的打开与关闭 2.1 流

流是一个高度抽象概念
 当前计算机具有大量不同设备,很多与I/O *** 作有关。


如:软盘、硬盘、通信端口、视屏适配器等。


每种设备具有不同的特性和 *** 作协议, *** 作系统负责与这些不同设备的I/O细节,并向程序员提供一个更为简单和统一的I/O接口
 C语言进一步对I/O接口进行抽象引入流的概念。


根据流的方向分为输入流和输出流。


程序要输入数据只需从输入流中读入;输出数据只需向输出流中写即可。


特定I/O设备的细节对程序员是隐藏的。


说明:每个C语言程序运行时默认打开3个流,分别为标准输入流(stdin)、标准输出流(stdout)、标准错误流(stderr)。


标准输入默认是键盘,标准输出默认是显示器

2.2 文件指针类型(FILE *)

每个被使用的文件都会在内存中开辟了一个对应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。


这些信息是保存在一个结构体变量中的。


该结构体类型是FILE类型,在中定义,我们也将这个结构体变量称为文件流

//VS2013 IDE中头文件对FILE的定义
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 * 的指针来维护这个FILE类型结构体变量,所以FILE * 指针指向一个文件流

FILE* pf;//文件指针变量

pf是一个指向FILE类型数据的指针变量。


可以使pf指向某个文件的文件信息区(是一个结构体变量),通过该文件信息区中的信息就能够访问该文件

2.3 文件流的打开和关闭

fopen函数功能:
打开一个指定文件,并返回一个指向该文件流(文件信息区)的FILE * 指针

库函数fopen函数声明
FILE * fopen ( const char * filename, const char * mode );
返回值:打开文件成功返回指向该文件流(文件信息区)的FILE * 指针,打开失败返回NULL指针,所以应该检查fopen函数的返回值
filename :需打开文件或设备名字,可以是绝对路径或相对路径写法
mode:文件打开模式

常用模式说明:
r :以只读方式打开文件,该文件必须存在
w :以只写方式打开文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。



a :以追加的方式打开只写文件。


若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件末尾
b :打开二进制文件,配合上面r、w、a使用

fclose函数功能:
刷新文件缓冲区,关闭一个指定文件(释放文件流)

库函数fclose函数声明
int fclose ( FILE * stream );
返回值:关闭成功返回0,失败返回EOF
stream:指向文件流的指针

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //以只读方式打开一个文件file.txt
	if (NULL == pf) //打开失败
	{
		perror("fopen"); //打印错误信息
		return -1; //退出程序
	}
	//读 *** 作
	fclose(pf); //关闭文件
	pf = NULL;
	return 0;
}

三、 顺序读写

顺序读写:对文件的输入和输出只能按照顺序读写

3.1 字符函数 3.1.1 字符输入 fgetc函数

fgetc函数功能:
返回指定流的位置指示器指向的字符,然后位置指示器向前移动一个字符,简单理解就是从指定流读取1个字符

库函数fgetc函数声明
int fgetc ( FILE * stream );
返回值:读取成功返回对应字符的ascii码值。


读取到文件结束标志时,则函数返回EOF并设置流的文件结束指示符(feof)。


如果发生读错误,该函数返回EOF并设置流的错误指示符(ferror)
stream:指向输入流(文件流、标准输入流)的指针

测试1:从文件中读取字符

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //file.txt存在,内容为hello
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	printf("%c\n", fgetc(pf)); //输出读取第1个字符
	printf("%c\n", fgetc(pf)); //输出读取第2个字符
	fclose(pf);
	pf = NULL;
	return 0;
}

输出

h
e

测试2:从标准输入中读取字符

#include 
int main()
{
	char c = fgetc(stdin);
	printf("%c\n", c);
	return 0;
}

输入

a

输出

a
3.1.2 字符输出 fputc函数

fputc函数功能:
将一个字符写入流并使位置指示器向前移动,即字符被写入到流的内部位置指示器所指示的位置,然后该位置指示器自动前进1,简单理解就是写1个字符到流中

库函数fputc函数声明
int fputc ( int character, FILE * stream );
返回值:如果成功,则返回所写的字符。


如果发生写错误,则返回EOF并设置错误指示器(ferror)。



character :待写入字符
stream:指向输出流(文件流、标准输出流)的指针

测试1:输出字符到文件

#include 
int main()
{
//将字符'a'  'b'  'c' 写入到文件
	FILE* pf = fopen("file.txt", "w");
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

测试2:输出字符到标准输出

#include 
int main()
{
	int c = fputc('h', stdout);
	c = fputc('e', stdout);
	c = fputc('l', stdout);
	return 0;
}

屏幕上显示

hel
3.2 未格式化文本行函数 3.2.1 未格式化文本行输入 pgets函数

fgets函数功能:
从流中读取num-1个字符到字符数组str中,或者遇到换行符或文件结束符停止(以最先发生的为准)。


换行符会使fgets停止读取,但函数会认为它是一个有效的字符,并添加’\0’使成为一个字符串

库函数fgetc函数声明
char * fgets ( char * str, int num, FILE * stream );;
返回值:读取成功,函数返回str。


如果在读取中时遇到文件结束符,则设置eof指示器(feof),返回一个空指针(str的内容保持不变)。



如果发生读错误,则设置错误指示符(ferror)并返回一个空指针 (但str所指向的内容可能已经改变)
str :字符数组的数组名
num:最多复制num个字符到str数组
stream:指向输入流(文件流、标准输入流)的指针

测试1:从文件中读取未格式文本行

#include 
int main()
{
	FILE* pf = fopen("file.txt", "r"); //文件file.txt内容为:Hello World
	if (NULL == pf)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	char arr[20] = "#################";
	fgets(arr, 5, pf); //读取5-1个字符到arr数组,并添加'printf'到数组,即"Hell"
	("%s",) arr;//打印Hell fgets
	(,arr5 ,) pf;读取5-1个字符到arr数组,并添加'printf'到数组,即"o Wo" (
	"%s",); arr//打印o Wofclose (
	);pf=NULL
	pf ; return0
	; }Hello Wo

#

输出

include

测试2:从标准输入中读取未格式化文本行

intmain 
( )char[
{
	] arr="##########" ; fgets(
	,6arr, stdin) ;printf(
	"%s\n",); arrreturn0
	; }abcdef

abcde

输入

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

输出

#
3.2.2 未格式化文本行输出 fputs函数

fputs函数功能:
将str指向的字符串写入流。


函数从指定的地址(str)开始复制,遇到’\0’停止。


'\0’不会复制到流中

库函数fputs函数声明
include
返回值:如果成功,将返回一个非负值。


在出错时,函数返回EOF并设置错误指示符(ferror)
str :需写入的字符串起始地址
stream:指向输出流(文件流、标准输出流)的指针

测试1 :输出未格式化文本行到文件

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","w") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }fputs
	(
	"Hello World",); pffputs(
	"Hello WuHan",); pffclose(
	);pf=NULL
	pf ; return0
	; }Hello WorldHello WuHan

#

打开file.txt文件发现内容为:

include

所以当要写入多行时需要在字符串中加入换行符,即 fputs(“Hello World\n”, pf);

测试2 :输出未格式化文本行到标准输出

intmain 
( )char[
{
	] arr1="Hello World\n" ; fputs(
	,stdoutarr1) ;fputs(
	"Hello Wuhan\n",stdout) ;return0
	; }Hello World
Hello Wuhan

long int ftell ( FILE * stream );;

屏幕上显示

#

四、随机读写

随机读写:以任意顺序读写文件的不同位置,文件的读写位置是由文件信息区(文件流)中位置指示器决定

4.1 获取文件当前位置 ftell函数

ftell函数功能:
返回流的位置指示器的当前值(文件当前位置)

库函数ftell声明
include
返回值:对于二进制流,这是当前位置距离文件起始位置之间字节数。


对于文本流,数值可能没有意义(因为不同系统换行符不一样,如:windwos换行符为\r\n  linux换行符为\n)。


失败返回-1L
stream:指向流的指针

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","r") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }long
	=
	ftell position ( );pf//获取文件当前位置printf (
	"文件当前位置:%d\n",); positionfgetc(
	);pf//读取位置指示器的字符,读完后位置指示器向前移动= ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionfclose(
	);pf=NULL
	pf ; return0
	; }0
1

输出

文件当前位置:void rewind ( FILE * stream );
文件当前位置:void rewind ( FILE * stream );
4.2 改变文件当前位置 fseek函数

fseek函数功能:
将流的位置指示器(当前位置)设置为指定位置,成功调用该函数后,清除流的文件结束符和错误内部指示符

库函数ftell声明
#
stream:指向流的指针

4.3 设置文件当前位置为起始位置 rewind函数

rewind函数功能:
将流的位置指示器(当前位置)设置为文件的起始位置,成功调用该函数后,清除流的文件结束符和错误内部指示符

库函数ftell声明
include
stream:指向流的指针

intmain 
( )*=
{
	FILEfopen pf ( "file.txt","r") ;if(
	NULL ==) printf pf(
	{
		"%s\n",strerror( ))errno;return1
		; }long
	=
	ftell position ( );pf//获取文件当前位置printf (
	"文件当前位置:%d\n",); positionfseek(
	,3pf, SEEK_SET) ;=ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionrewind(
	);pf=ftell
	position ( );pfprintf(
	"文件当前位置:%d\n",); positionfclose(
	);pf=NULL
	pf ; return0
	; }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/578205.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存