C语言-对文件的输入输出

Posted 霏ིྀ宇ིྀ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言-对文件的输入输出相关的知识,希望对你有一定的参考价值。

C语言中的文件类型

主要是两种文件类型:1. 文本文件(ASCII),2.二进制文件
一般来说,人类可读的文件都作为文本文件,例如一片文章。其余都作为二进制文件,例如一个程序。

ASCII码文件每一个字节存放一个ASCII代码,代表一个字符,因此便于对字符进行逐个处理,也便于输出字符。但是一般占存储空间较多,而且要花费转换时间(二进制形式与ASCII码间的转换)。
二进制文件是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。用二进制输出数值,可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。一般中间结果数据需要暂时保存在外存上以后又需要输入到内存的,常用二进制文件保存

文件缓冲区

缓冲区文件系统:系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区。

非缓冲区文件系统:系统不自动开辟确定大小的缓冲区,而由程序为每个文件设定缓冲区。

文件类型指针

在C语言中用一个指针变量指向一个文件,这个指针称为文件指针。通过文件指针就可对它所指的文件进行各种操作。

定义说明文件指针的一般形式为:

FILE *指针变量标识符;
其中FILE应为大写,它实际上是由系统定义的一个结构,该结构中含有文件名、文件状态和文件当前位置等信息。在编写源程序时不必关心FILE结构的细节。
在使用文件时,需要在内存中为其分配空间,用来存放文件的基本信息,给结构体类型是由系统定义的,C语言规定该类型为FILE型,其声明如下:

typedef  struct
     short  level;                         // 缓冲区“满”或“空”的程度  
      unsigned  flags;                  // 文件状态标志  
      char  fd;                              // 文件描述符   
      unsigned  char  hold;        //  如无缓冲区不读取字符 
      short   bsize;                       // 缓冲区的大小 
      unsigned  char  * buffer;   // 数据缓冲区的位置 
      unsigned  char  *curp;      // 指针,当前的指向 
      unsigned       istemp;          // 临时文件,指示器  
      short  token;                      // 用于有效性检查 
  FILE;

例如:FILE *fp;

表示fp是指向FILE结构的指针变量,通过fp即可找存放某个文件信息的结构变量,然后按结构变量提供的信息找到该文件,实施对文件的操作。习惯上也笼统地把fp称为指向一个文件的指针。

文件的打开与关闭(fopen,fclose)

下面是这个函数调用的原型:

FILE *fopen( const char * filename, const char * mode );

由于文件的打开与关闭都是利用系统函数来实现的,因此,在编写有关文件的程序时,应该在其中包含“stdio.h”头文件。

文件的打开(fopen 函数)

FILE * fp;

fp=  fopen (文件名, 使用文件方式)

例如: fp=fopen ( "a1", "r");

文件名:参数为字符指针类型,实参为带路径的字符串。
使用文件方式:参见表下表。
“r”、“w”、“a”、 “r+”、“w+”、“a+”
“rb”、“wb”、“ab”、 ……

说明: “r”、“w”、"a"等打开文件的方式。
打开文件的常规方式:

if ( ( fp=fopen ("file1","r"))==NULL)
  printf("Cannot open this file \\n");
   exit(0);

文件中的回车换行符<=>内存中的换行符。

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


对上表做以下补充说明:

1.  程序中凡是用“r”打开一个文件时,表明该文件必须已经存在,且只能从该文件读出数据。

2.用“w”打开的文件也只能向该文件写入数据。若打开的文件不存在,则按照指定的文件名建立该文件,若打开的文件已经存在,则将该文件删除,重建一个新文件。使用时要特别注意这一点。

3.  如果要向一个已经存在的文件后面追加新的信息,那只能用“a”方式打开文件。但此时该文件必须是存在的,否则将会出错。 

在打开一个文件之前,应该定义文件型指针,以便接收函数fopen返回的地址。如果出错,fopen将返回一个空指针NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并做相应的处理。
例如:

if((fp=fopen(“file1”,”rb”))= =NULL)
            
                printf(“\\n error on open file1”);
                getch( );
                exit(1);
             

该程序段表示:如果返回的指针为空,则不能打开当前目录下的文件“file1”,同时给出错误提示信息“error on open file1”。程序中的getch()函数的功能是从键盘输入一个字符,该字符不在屏幕上显示。其实getch()在这里的作用是停留等待,只有当用户从键盘敲任意键时,程序才继续执行,我们可以利用这个等待时间来阅读出错提示,找到错误原因。当敲任意键后,执行语句“exit(1);”,从而退出程序。

文件的关闭

文件一旦使用完毕,应使用关闭文件函数fclose把文件关闭,以避免文件数据丢失等情况的发生。

fclose函数调用的一般形式为:

 fclose(FILE *fp);

其中,参数fp是文件型指针,通过fopen()函数已经获得,它指向某个打开的文件。例如:

fclose(fp);

上述语句的含义是关闭fp所指向的文件,同时自动释放分配给文件的内存缓冲区。当正常完成关闭文件的操作时,fclose函数的返回值为0,表示已正确关闭指定的文件;如返回非0值则表示有错误发生。

【例】文件的打开与关闭应用举例。

#include <stdio.h>
 
int main()

   FILE *fp = NULL;
 
   fp = fopen("/tmp/test.txt", "w+");
   fprintf(fp, "This is testing for fprintf...\\n");
   fputs("This is testing for fputs...\\n", fp);
   fclose(fp);

文件的读写(fputc,fgetc, fread,fwrite函数)

文件的读写操作由文件读写函数完成,常用的读写函数有fputc、fgetc、fread、fwrite、fputs、fgets、fprintf、fscanf、putw、getw等。

函数名调用方式功能返回值
fputcfputc( ch, fp)把字符写入文件指针变量 fp指向的文件输出成功,返回被写入的字符如果发生错误,则返回 EOF,并设置错误标识符
fgetcfgetc(fp)从fp指向的文件读入一个字符读成功,带回所读的字符,失败则返回文件结束的EOF(即-1)

说明: fgetc的第一个字符f代表文件(file),中间的get表示获取,最后一个c表示字符。

字符读写函数

读字符函数——fgetc函数

#include <stdio.h>

int main ()

   FILE *fp;
   int c;
   int n = 0;
  
   fp = fopen("file.txt","r");
   if(fp == NULL) 
   
      perror("打开文件时发生错误");
      return(-1);
   
   do
   
      c = fgetc(fp);
      if( feof(fp) )
      
          break ;
      
      printf("%c", c);
   while(1);

   fclose(fp);
   return(0);

写字符函数——fputc函数

#include <stdio.h>
 
int main ()

   FILE *fp;
   int ch;
 
   fp = fopen("file.txt", "w+");
   for( ch = 33 ; ch <= 100; ch++ )
   
      fputc(ch, fp);
   
   fclose(fp);
 
   return(0);

#include <stdio.h>
 
int main ()

   FILE *fp;
   int c;
 
   fp = fopen("file.txt","r");
   while(1)
   
      c = fgetc(fp);
      if( feof(fp) )
      
          break ;
      
      printf("%c", c);
   
   fclose(fp);
   return(0);

例10.1 从键盘输入一些字符,逐个把他们送到磁盘上去,直到用户输入一个“#”为止。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int main()

	FILE * fp;
	char ch, filename[10];
	printf("请输入所用的文件名:\\n");
	scanf("%s", filename);
	if ((fp =fopen(filename, "w")) == NULL)
	
		printf("无法打开此文件:\\n");
		exit(0);
	
	ch = getchar();
	printf("请输入一个准备存储到磁盘的字符串(以#结束):");
	ch = getchar();
	while (ch != '#')
	
		fputc(ch, fp);
		putchar(ch);
		ch = getchar();
	
	fclose(fp);
	putchar(10);
	return 0;

例10.2从键盘输入一些字符,逐个把他们送到磁盘上去,直到用户输入一个“#”为止。

#include <stdio.h>
#include <stdlib.h>
int main()

	FILE* in, * out;
	char ch, infile[50], outfile[50];	//文件字符数组要大于文件名称所占字符数
	printf("enter the name of the read in file:\\n");
	scanf("%s", infile);
	printf("enter the name of the out in file:\\n");
	scanf("%s", outfile);
	if ((in = fopen(infile, "r")) == NULL)
	
		printf("error\\n");
		exit(0);
	
	if ((out = fopen(outfile, "w")) == NULL)
	
		printf("error\\n");
		exit(0);
	
	while (!feof(in))
	
		ch = fgetc(in);
		fputc(ch, out);
		putchar(ch);
	
	putchar(10);
	fclose(in);
	fclose(out);
	return 0;

【例10.3】从键盘输入若干个字符串,对它们按字母大小的顺序排序,然后把排好序的字符串送到磁盘文件中保存。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()

	FILE *fp;
	char str[3][10],temp[10];
	int i,j,k,n=3;
	printf("Enter strings:\\n");
	for(i=0;i<n;i++)
		gets(str[i]);
	
	for(i=0;i<n-1;i++)
	
		k=i;
		for(j=i+1;j<n;j++)
		
			if(strcmp(str[k],str[j])>0)
				k=j;
		
		if(k!=i)
		
			strcpy(temp,str[i]);
			strcpy(str[i],str[k]);
			strcpy(str[k],temp);
		
	
	if((fp=fopen("D:\\\\CC\\\\string.dat","w"))==NULL)
	
		printf("can't open file!\\n");
		exit(0);
	
	printf("\\nThe new sequence:\\n");
	for(i=0;i<n;i++)
	
		fputs(str[i],fp);
		fputs("\\n",fp);
		printf("%s\\n",str[i]);
	
	return 0;

在VS2019下,需将源文件的gets、strcpy、fopen做些修改:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()

	FILE* fp;
	char str[3][10], temp[10];
	int i, j, k, n = 3;
	printf("Enter strings:\\n");
	for (i = 0; i < n; i++)
		gets_s(str[i], 10);

	for (i = 0; i < n - 1; i++)
	
		k = i;
		for (j = i + 1; j < n; j++)
		
			if (strcmp(str[k], str[j]) > 0)
				k = j;
		
		if (k != i)
		
			strcpy_s(temp, strlen(str[i]) + 1, str[i]);
			strcpy_s(str[i], strlen(str[k]) + 1, str[k]);
			strcpy_s(str[k], strlen(temp) + 1, temp);
		
	
	fopen_s(&fp, "D:\\\\CC\\\\string.datt", "w");
	if (fp == NULL)
	
		printf("can't open file!\\n");
		exit(0);
	
	printf("\\nThe new sequence:\\n");
	for (i = 0; i < n; i++)
	
		fputs(str[i], fp);
		fputs("\\n", fp);
		printf("%s\\n", str[i]);
	
	return 0;

例10.3读回字符串:

#include<stdio.h>
#include<stdlib.h>

int main()

	FILE *fp;
	char str[3][10];
	int i=0;
	if((fp=fopen("D:\\\\CC\\\\string.dat","r"))==NULL)
	
		printf("can't open file!\\n");
		exit(0);
	
	while(fgets(str[i],10,fp)!=NULL)
	
		printf("%s",str[i]);
		i++;
	
	fclose(fp);
	return 0;

在VS2019下,需将源文件的fopen做些修改:

#include<stdio.h>
#include<stdlib.h>

int main()

	FILE* fp;
	char str[3][10];
	int i = 0;
	fopen_s(&fp,"D:\\\\CC\\\\string.dat", "r");
	if (fp== NULL)
	
		printf("can't open file!\\n");
		exit(0);
	
	while (fgets(str[i], 10, fp) != NULL)
	
		printf("%s", str[i]);
		i++;
	
	fclose(fp);
	return 0;

字符串读写函数

字符串读写函数处理的文件类型主要是文本文件,分为读字符串函数和写字符串函数

写字符串函数——fputs

fputs函数的功能是向指定的文件写入一个字符串,其调用形式为:

fputs(字符串,文件指针);

字符串可以是字符串常量,也可以是字符数组名或指针变量,例如:

fputs(“Human”,fp);

上述语句的含义是把字符串“Human”写入fp所指的文件之中。

读字符串函数——fgets

fgets函数的功能是从指定的文件中读一个字符串到字符数组中,其调用形式为:

fgets (str,n,fp);

函数中的参数str是字符数组名;n是一个正整数,表示从文件中读出的字符串不超过n-1个字符。在向字符数组读入的最后一个字符后加上字符串结束标志’\\0’。如果在读n-1个字符之前遇到换行符或EOF,读入工作结束。例如:

fgets (ch,50,fp);
 上述语句的含义是从fp所指的文件中读出49个字符送入字符数组ch中。

【例10.3】从键盘输入若干个字符串,对它们按字母大小的顺序排序,然后把排好序的字符串送到磁盘文件中保存。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()

	FILE *fp;
	char str[3][10],temp[10];
	int i,j,k,n=3;
	printf("Enter strings:\\n");
	for(i=0;i<n;i++以上是关于C语言-对文件的输入输出的主要内容,如果未能解决你的问题,请参考以下文章

c语言如何对字符串进行位置查询

c语言程序设计请编写一个函数fun,它的功能是:将ss所指字符串中所有下标为奇数位置上的字母转换为

c怎样在文件中插入数据

C语言求平均值

ZZNUOJ_用C语言编写程序实现1177:字符串排序(指针专题)(附完整源码)

C语言试题三十六之将s所指字符串中所有下标为奇数位置上的字母转换为大写(若该位置上不是字母,则不转换)。