C语言文件的读写操作

目录

一,文件

1.文本模式,二进制模式

2.标准文件

二,文件的打开和关闭

1.文件指针

1.1文件的打开

 1.2文件的关闭

三,文件的顺序读写 

1.fgetc

2.fputc

3.fgets

4.fputs

5.fprintf

6.fscanf

7.fwrite

8.fread

 9.表格

四,文件的随机读写

1,fseek 

 2,ftell

3,rewind

判断文件结束

1,feof

2,判断结束

文件使用模式(表格)

文本文件的部分代码示例

二进制文件的部分代码


一,文件

C把文件看作是一系列的连续的字节,每个字节都能被单独读取。

C提供两种文件模式:文本模式和二进制模式

1.文本模式,二进制模式

   首先要区分文本内容和二进制内容,文本文件格式和二进制文件格式,及文件的文本模式和二进制模式。

  1. 文本内容:如果文件最初使用的是二进制编码的字符(如ASCII码)表示文本,该文件就是                      文本文件,其中包含文本内容。
  2. 二进制内容:如果文件中的二进制值代表机器语言代码或数值数据,图片或者音乐编码,该                       文件就是二进制文件,其中包含二进制内容。

2.标准文件

  c程序自动打开的三个文件

  1. 标准输入(stdin):为程序提供输入,getchar()和scanf()使用的文件。
  2. 标准输出(stdout):为程序提供输出,putchar()、printf()和puts()使用的文件。
  3. 标准错误输出(stderr):提供一个逻辑上不同的地方来发送错误信息。

二,文件的打开和关闭

1.文件指针

每个被使用的文件都在内存中开辟了一个相对应的文件信息区,用来存放文件的相关信息。这些信息是保存在一个结构体变量中的,这个结构体类型是由系统声明的取名FILE(文件)。

定义一个文件指针变量:

FILE * pf ;//文件指针变量,指向被操作的文件

1.1文件的打开

  打开文件我们用到一个打开文件的函数 fopen()查找库函数得知 :

C语言文件的读写操作_第1张图片

所以我们用文件指针接受打开的文件可操作流:

FILE * pf = fopen("文件名.后缀","打开方式");
//打开文件之后要判断有没有打开成功
if(pf==NULL) //打开失败返回NULL
 perror("fopen");
 //perror报错函数,会打印括号里面的错误信息

是一个高度抽象的概念:

         程序直接传输到外部设备比较繁琐,所以写入流,让流操作

 下述所有的流 同时包括 FILE文件指针pf。

 1.2文件的关闭

      关闭与流关联的文件并取消关联,使用fcloae():

fclose(pf);//关闭文件
pf=NULL; //置空指针

注意

  1. 打开文件是有限的,只打开不释放,最后会打不开文件。
  2. 路径错误也会导致打不开文件
  3. 可以用绝对路径打开文件,但是要注意转义字符(目录下的绝对位置,直接到达目标位置,通常是从盘符开始的路径)。

      

三,文件的顺序读写 

       先简单介绍所有的读写函数,然后再附上表格。

       所有用到的pf都表示文件指针。

1.fgetc

从流中获取字符

参数是标准输入流 

        读一次向后移动 1 ,类似于指针的 ++ ,当读取超出文件长度 出EOF(-1) ;

int ret =  fgetc(pf);

2,fputc

将字符写入流

 两个参数一个是 字符,一个是 标准输出流(stdout,stderr)

fputc('字符',输出流);

3.fgets

从流中获取字符串写入目标数组

 

第一个参数是 目标数组的指针;

第二个复制到数组的最大个数(n-1个,最后一个放'\0');

第三个参数是标准输入流。

fgets(arr,4,pf);

4.fputs

将字符串写入流

第一个参数是要写入流的地址指针;

第二个参数是标准输出流。

fputs("abcdef\n",pf);

5.fprintf

将格式化数据写入流

第一个参数是标准输出流

第二个参数是格式化字符串等一系列的东西

Typedef struct S{
  char arr[10];
  int num;
  float sc;
}s;
fprintf(pf,"%s %d %d ",s.arr,s.num,s.sc) ;

6.fscanf

从流中读取格式化数据

第一个参数是标准输入流

第二个参数是格式化字符串等一系列的东西

fscanf(pf,"%s %d %f",&(s.arr),&(s,num),&(s.sc));

7.fwrite

以二进制的方式写文件

第一个参数是写入元素数组的指针

第二个参数是要写入的每个元素的大小(单位字节)

第三个参数是要写入的元素个数

第四个参数是要被写入的地址

fwrite(&s,sizeof(struct S) , 1 ,pf) ;
//从s中找到1个元素,元素大小是sizeof(struct S)的数据,写到pf中

8.fread

以二进制的方式读文件

第一个参数是接收读取文件内容的地址

第二个参数是要读取文件的大小

第三个参数是要读取文件的个数

第四个参数是被读取文件的地址

fread(&s,sizeof(struct S),1,pf);
//从pf里读取1个大小为sizeof(struct S)的文件到s中去

 9.表格

函数 功能 适用于
fgetc 字符输入函数(读文件 所有输入流
fputc 字符输出函数(写文件 所有输出流
fgets 文本行输入函数(读一行 所有输入流
fputs 文本行输出函数(写一行 所有输出流
fscanf 格式化输入函数 ( 所有输入流
fprintf 格式化输出函数( 所有输出流
fread 二进制输入  ( 文件
fwrite 二进制输出  ( 文件

这里会有些迷惑,为什么输出函数后面会标注 写,输入函数后面 标注 读 。

这里的读写 是面向内存的,也就是说对于用户来说的输入,对于内存来说是读,就是读取用户的输入信息,或者是别的位置的数据;对用户来说的输出,对于内存来说是写,就是写出信息让用户可以看到。

四,文件的随机读写

1,fseek 

根据文件指针的位置和偏移量来定位文件指针

第一个参数 流

第二个参数 偏移量

第三个参数 起始位置

起始位置选项: SEEK_CUR :文件当前位置开始

                          SEEK_END : 文件末尾位置开始

                          SEEK_SET  : 文件起始位置开始

 2,ftell

返回文件指针的当前位置

 参数是 流

3,rewind

让文件指针回到起始位置

 参数是 流

判断文件结束

1,feof

当文件读取结束时,判断文件是读取失败结束,还是遇到文件尾(读取完成)结束。

2,判断结束

判断结束不可以用feof的返回值直接判断文件是否结束,但可以通过以下几种方式:

  1. fgets 判断返回值是否为 EOF
  2. fgets 判断返回值是否为NULL
  3. fread判断返回值是否小于实际要读取的个数

文件使用模式(表格)

文件使用方式 含义 如果指定文件不存在
" r "     (只读) 为了输入数据,打开一个已经存在的文本文件 出错
" w "    (只写) 为了输出数据,打开一个文本文件 建立一个新的文件
" a "     (追加) 向文本文件尾部添加数据 建立一个新的文件
" rb "    (只读) 为了输入数据,打开一个二进制文件 出错
" wb "   (只写) 为了输出数据,打开一个二进制文件 建立一个新的文件
" ab "    (追加) 向一个二进制文件尾部添加数据 出错
" r+  "    (读写) 为了读写,打开一个文本文件 出错
" w+ "   (读写) 为了读写,建立一个新的文本文件 建立一个新的文件
" a+ "    (读写) 打开一个文件,在文件尾部进行读写 建立一个新的文件
"rb+  "   (读写) 打开一个二进制文件(读写) 出错
" wb+ "  (读写) 建立一个新的二进制文件(读写) 建立一个新的文件
" ab+ "  (读写) 打开一个二进制文件,在文件尾部进行读和写 建立一个新的文件

" wx " ," wbx " , " w+x " , " wb+x " 或 " w+bx "

类似于不含有x的模式,如果文件已经存在或以独占模式被打开,则打开文件失败


文本文件的部分代码示例

 int c; //处理EOF,EOF的值是-1,不可以用 char类型 
 FILE *pf = fopen("test.c","r") ;//这里的文件名知识一个例子
 if(!pf)//判断打开文件是否成功
{
 perror("FILE error"); 
 return EXIT_FAILURE;//值为1, 运行程序失败
}
//fgetc读取失败时或者遇到文件结尾时返回EOF
 while((c = fgetc(pf) ) != EOF)
{
 putchar(c); 
}
//判断结束原因
 if(ferror(pf))
{
 printf("I/O error");
} 
 else if(feof(pf) ) //前一个没有出现错误说明是正常结束
{
 printf("END of FILE ……");
}
//ferroe 初始化为0 ,返回非0 的时表面出错

//关闭文件
fclose(pf);

二进制文件的部分代码

enum {
	size = 5
};
//枚举 ,后面的size大小是5
double a[size] = { 1,2,3,4,5 };
FILE * pf = fopen("test.c", "wb"); //打开文件
fwrite(a, sizeof(a), size, pf); //fwirte的返回值是一个size_t类型
fclose(pf);//关闭文件

double b[size];
FILE * pf = fopen("test.c", "rb");
size_t ret = fread(b, sizeof(b), size, pf);//读取

if(ret == 1) //当ret == 1 时,读取成功
{
	puts("successfully :");
	for (int n = 0; n < size; n++)//打印内容
	{
		printf("%f ",b[n]);
	}
	putchar('\n');
}
else //失败时判断失败的原因
{
	if (feof(pf))
	{
		printf("end of file:");
	}
	else if (ferror(pf))
	{
		perror("Error:");
	}
}
fclose(pf);//关闭文件

上述两个代码段,需要放到具体内容里,用合适的变量接受具体的返回值,返回值类型上文都有介绍。

你可能感兴趣的:(从零开始的编程生活,c语言)