当前位置: 首页 > news >正文

C语言文件操作

一、有关文件的概念

一般我们所说的文件指的是磁盘上的文件,而程序设计中我们所说的文件主要包含两种:程序文件、数据文件。

程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀 为.exe)。

数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

1.文件名:一个文件要有一个唯一的文件标识,以便用户识别和引用。 文件名包含3部分:文件路径+文件名主干+文件后缀 例如: c:\code\test.txt 为了方便起见,文件标识常被称为文件名

2.文件类型:根据数据的组织形式,数据文件被称为文本文件或者二进制文件数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件

3.数据在内存中的存储

字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。 如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输 出,则在磁盘上只占4个字节

4.文件的缓冲区

ANSIC 标准采用缓冲文件系统处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘 上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据c编译系统决定的。

5.文件指针

缓冲文件系统中,关键的概念是文件类型指针,简称文件指针。每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及 文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名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*类型的指针,指向该文件。而打开文件需要使用fopen函数,关闭文件需要使用fclose函数。具体代开文件的方式有以下几种:

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

 

 

 

 

 

 

 

 

 

 

 

 

 

1.fopen函数和fclose函数

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

//filename为文件名,mode为打开类型

int fclose ( FILE * stream );

//stream为需要关闭的文件

2.打开文件的路径

打开文件时,需要制定文件路径和文件名,这样才能准确的找到需要打开的文件或者需要建立的文件的路径和文件名。打开文件的路径主要有默认路径和指定路径,默认路径就是指直接在当前目录打开或新建一个文件,而指定路径也有两种方式,一种是相对路径另一种是绝对路径(直接从当前目录打开或新建的方式也属于相对路径)。

相对路径:.\Debug\test.txt

绝对路径:C:\Users\user\Documents\Visual Studio 2013\Projects\Project1

代码示例:

int main()
{
	//文件的打开和关闭举例
	FILE* f1;
	//注意:c语言中的‘\’是转义字符,如果想使用的不是转义需要进行二次转义,即输入两个\\
	
	//绝对路径:从桌面以只写的方式打开txt.c文件
	f1 = fopen("C:\\Users\\user\\Desktop\\test.txt","w");
	if (f1 == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}
	//关闭f1文件
	fclose(f1);

	//以只写的方式从当前目录打开一个文件
	f1 = fopen("test.txt","w");
	if (f1 == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}
	//关闭f1文件
	fclose(f1);

	//当前目录的下一级Debug目录打开一个文件
	f1 = fopen(".\\Debug\\test.txt", "w");
	if (f1 == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}
	//关闭f1文件
	fclose(f1);
	return 0;
}

三、文件的读写

1.文件的顺序读写

fegtc函数

int fgetc ( FILE * stream );

//字符输入,从文件中读出一个字符

int main()
{
	FILE* pfile1;
	pfile1 = fopen("C:\\Users\\user\\Desktop\\test.txt", "r");
	if (pfile1 == NULL)
	{
		printf("失败\n");
		exit(-1);
	}
    //需要提前手动向文件中写入内容,或打开一个有内容的文件
	printf("%c", fgetc(pfile1));
	fclose(pfile1);
	return 0;
}

 

fputs函数 

int fputc ( int character, FILE * stream );

//字符输出函数,读入一个字符到文件

int main()
{
	FILE* pfile1;
	pfile1 = fopen("C:\\Users\\user\\Desktop\\test.txt","w");
	if (pfile1 == NULL)
	{
		printf("失败\n");
		exit(-1);
	}
	fputc('h',pfile1);
	fclose(pfile1);
	return 0;
}

 fgets函数

char * fgets ( char * str, int num, FILE * stream );

//文本行输入函数,从文件中读出num个字符到str中

int main()
{
	FILE* pfile1;
	char* str = (char*)malloc(11);
	pfile1 = fopen("C:\\Users\\user\\Desktop\\test.txt", "r");
	if (pfile1 == NULL)
	{
		printf("失败\n");
		exit(-1);
	}
	fgets(str, 11, pfile1);
	printf("%s",str);
	fclose(pfile1);
	return 0;
}

fputs函数 

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

//文本行输出函数,向文件中写入字符串str

int main()
{
	FILE* pfile1;
	char* str = "hello world1";
	pfile1 = fopen("C:\\Users\\user\\Desktop\\test.txt", "w");
	if (pfile1 == NULL)
	{
		printf("失败\n");
		exit(-1);
	}
	fputs(str,pfile1);
	fclose(pfile1);
	return 0;
}

 fscanf函数

int fscanf ( FILE * stream, const char * format, ... );

//格式化输入函数,从文件中格式化读出

int main()
{
	FILE* pfile1;
	char* str = (char*)malloc(11);;
	pfile1 = fopen("C:\\Users\\user\\Desktop\\test.txt", "r");
	if (pfile1 == NULL)
	{
		printf("失败\n");
		exit(-1);
	}
	fscanf(pfile1,"%s",str);
	printf("%s\n",str);
	fclose(pfile1);
	return 0;
}

  fprintf函数

int fprintf ( FILE * stream, const char * format, ... );

//格式化输出函数,按照指定格式输出到文件

int main()
{
	FILE* pfile1;
	char* str = "hello world1";
	pfile1 = fopen("C:\\Users\\user\\Desktop\\test.txt", "w");
	if (pfile1 == NULL)
	{
		printf("失败\n");
		exit(-1);
	}
	fprintf(pfile1, "%s", str);
	fclose(pfile1);
	return 0;
}

 fread函数和fwrite函数

二进制输入输出函数,用法跟fscnaf函数和fprintf函数类似。

2.文件的随机读写

fseek函数

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

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

int main()
{
	FILE * pFile;
	pFile = fopen("C:\\Users\\user\\Desktop\\example.txt", "wb");
	fputs("This is an apple.", pFile);
	fseek(pFile, 9, SEEK_SET);
    //SEEK_SET是一个宏常量,值为0
	fputs(" sam", pFile);
	fclose(pFile);
	return 0;
}

 

ftell函数

long int ftell ( FILE * stream );

//返回文件指针相对于起始位置的偏移量

#include <stdio.h>
int main ()
{
      FILE * pFile;
      long size;
      pFile = fopen ("myfile.txt","rb");
      if (pFile==NULL) 
        perror ("Error opening file");
      else
     {
        fseek (pFile, 0, SEEK_END);   // non-portable
        size=ftell (pFile);
        fclose (pFile);
        printf ("Size of myfile.txt: %ld bytes.\n",size);
     }
      return 0; 
}

 

rewind函数

void rewind(FILE* stream);

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

四、文件结束的判断

被错误使用的 feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束

1. 文本文件读取是否结束,判断返回值是否为EOF fgetc),或者NULLfgets

例如: fgetc判断是否为EOF. fgets判断返回值是否为NULL.

2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。

例如:read判断返回值是否小于实际要读的个数

文本文件判断文件结束

#include <stdio.h>
#include <stdlib.h>
int main(void) 
{
    int c; // 注意:int,非char,要求处理EOF
    FILE* fp = fopen("test.txt", "r");
    if(!fp) 
    {
        perror("File opening failed");
        return EXIT_FAILURE;
   }
 //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
    while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
   { 
       putchar(c);
   }
 //判断是什么原因结束的
    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
        puts("End of file reached successfully");
    fclose(fp);
}

二进制文件判断文件结束

#include <stdio.h>

enum { SIZE = 5 };
int main(void) 
{
    double a[SIZE] = {1.0,2.0,3.0,4.0,5.0};
    double b = 0.0;
    size_t ret_code = 0;
    FILE *fp = fopen("test.bin", "wb"); // 必须用二进制模式
    fwrite(a, sizeof(*a), SIZE, fp); // 写 double 的数组
    fclose(fp);
    fp = fopen("test.bin","rb");
    // 读 double 的数组
    while((ret_code = fread(&b, sizeof(double), 1, fp))>=1)
   {
        printf("%lf\n",b);
   }
    if (feof(fp))
        printf("Error reading test.bin: unexpected end of file\n");
    else if (ferror(fp)) 
    {
        perror("Error reading test.bin");
   }
    fclose(fp);
    fp = NULL; 
}

 

相关文章:

  • C语言程序的编译和链接
  • nowcoder---统计子串个数(C语言)
  • LeetCode---搜索二维矩阵(c语言)
  • C语言编程过程中与到的问题(不定时更新)
  • 计算机中加减乘除的实现
  • Linux基本指令+使用举例、权限的认识和相关指令、Linux添加删除用户、shell的理解(超详细)
  • Linux连接网络、修改账户密码
  • LeetCode---删除排序数组中的重复项(C语言)
  • LeetCode---合并两个有序数组
  • leetcode---返回链表的中间节点
  • 学生成绩管理系统---数据结构、C语言课程设计
  • 数据结构课程设计---学生成绩管理系统
  • leetcode---环形链表(快慢指针证明)
  • leetcode---环形链表II
  • 剑指offer---复制带随机值的链表
  • php的引用
  • JavaScript 如何正确处理 Unicode 编码问题!
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • Android Volley源码解析
  • C++类中的特殊成员函数
  • java8 Stream Pipelines 浅析
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • js递归,无限分级树形折叠菜单
  • Redis 中的布隆过滤器
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • vue-loader 源码解析系列之 selector
  • 多线程 start 和 run 方法到底有什么区别?
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 免费小说阅读小程序
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 使用 Docker 部署 Spring Boot项目
  • 想写好前端,先练好内功
  • ###C语言程序设计-----C语言学习(6)#
  • #QT(串口助手-界面)
  • $.ajax,axios,fetch三种ajax请求的区别
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (10)STL算法之搜索(二) 二分查找
  • (39)STM32——FLASH闪存
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (初研) Sentence-embedding fine-tune notebook
  • (转)Windows2003安全设置/维护
  • (转)母版页和相对路径
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .java 9 找不到符号_java找不到符号
  • .net 7 上传文件踩坑
  • .NET Core 成都线下面基会拉开序幕
  • .NET Remoting学习笔记(三)信道
  • .net 调用php,php 调用.net com组件 --
  • .NET 读取 JSON格式的数据
  • .net 发送邮件