首页 > 其他分享 >C语言学习记录(终)

C语言学习记录(终)

时间:2023-04-02 15:13:08浏览次数:40  
标签:fp 文件 函数 记录 int C语言 学习 FILE 指针

C语言学习记录(终)

一、知识要点(文件)

一、文件和文件类型指针

1、流和文件的概念

  • 流的概念
    • 我们不管什么物理设备硬件什么的,就把数据的输入输出抽象化为一种流,这样就可以方便编程,具有通用性。
    • 流分为文本流和二进制流
      • 文本流中的数据以字符形式存放,每个字符用ASCII码表示,占一个字节
      • 二进制流中的数据以内存存储形式存放, 即根据数据类型分配大小,用二进制码表示
  • 文件的概念
    • 从用户角度上来看,文件分为普通文件和设备文件
      • 普通文件是驻留在外部介质中的有序数据集。普通文件有程序文件和数据文件,源文件、目标文件、可执行文件就是程序文件,输入输出数据文件就是数据文件。
      • 设备文件就是与主机相连的各种外部设备,在操作系统中把外部设备当作文件来进行管理。
    • 从文件编码来看,文件分为ASCII码文件和二进制码文件
      • ASCII码文件又称文本文件,其内容是由一个个字符组成,每个字符对应一个字节,用于存放对应的ASCII码。如10000按ASCII码输出:00110001 00110000 00110000 00110000 00110000,占五个字节。
      • 二进制码文件的数据存储方式和在内存中的一样,如10000是整形,那么00000000 00000000 00100111 00010000,占四个字节。
      • 二进制文件输入输出速度较快,适合作中间结果,待后续处理;而ASCII码文件适合让人方便阅读。
  • 流和文件
    • 输入输出数据流的开始和结束仅受程序控制而不受物理符号控制的文件,叫做流式文件
    • 执行程序时会自动打开三种文件及其并联的流标准输入流、标准输出流和标准错误流,是用文件指针stdin、stdout、stderr操作的。
    • C语言中对文件的处理方法有缓冲文件系统和非缓冲文件系统
      • 缓冲系统文件就是系统自动在内存区为每个正在使用的文件开辟一个缓冲区,内存和磁盘输入输出数据必须先送到缓冲区,等缓冲区装满后在送出去,相当于仓库
      • 非缓冲文件系统的缓冲区要用户自己创建。

2、文件类型的指针

  • 文件类型

    • 系统给每个打开的文件分别在内存中开辟一个区域,将文件的有关信息存在一个结构变量中。该结构类型由系统定义,取名为FILE,称为文件类型,他是在头文件stdio.h中定义的。

    • typedef struct
      {
          short lever;			//缓冲区满或空的状态
          unsigned flags;			//文件状态标志
          char fd;				//文件描述符
          unsigned char hold;		//如无缓冲区不读取字符
          short size;				//缓冲区的大小
          unsigned char *buffer;	//数据缓冲区的位置
          unsigned char *curp;	//当前活动指针
          unsigned istemp;		//文件临时指示器
          short token;			//用与有效性检查
      }FILE;
      
  • 文件指针

    • 在C语言中用一个指针变量指向一个文件,这个指针叫文件指针。通过文件指针可以对所指的文件进行各种操作。
    • 定义文件指针的语法格式:FILE *指针变量名;

二、文件的打开和关闭

1、文件的打开

  • 在对文件进行读写之前,必须先执行打开文件的操作。文件的打开操作表示给文件分配一个FILE结构区,并将结构的指针返回给用户,用户就可以用FILE指针来操作文件了

  • 打开文件要调用fopen()函数完成,其原型为FILE *fopen(char *filename, char *type);。其中filename是要打开文件的文件名,type表示对文件的操作方式。

  • fopen()成功打开文件时,该函数会返回一个FILE指针,打开失败则返回NULL指针

  • 文件的使用方式说明

    • 文件使用方式由r,w,a,t,b,+这六个字符拼成,其含义为:
      r(read)
      w(write)
      a(append) 追加
      t(text) 文本文件,可省略不写
      b(binary) 二进制文件
      + 读和写

    • 用r打开文件时,该文件必须存在,且只能从该文件读出。

    • 用w打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件;若打开的文件已存在,则删去该文件,并以此文件名重建一个文件

    • 用a打开文件时,可以在已存在的文件中追加新的信息。如果文件不存在,则会出错。

    • 文件打开失败时会返回NULL指针,因此可以用下面的程序段打开文件。

      FILE *fp;
      
      if ((fp = fopen("c:\\hzk16", "rb")) == NULL)		//如果文件打开失败返回NULL指针,则提示无法打开
      {
          printf("\nerror on open c:\\hzk16 file!");
          
          exit(1);		//终止程序
      }
      
    • 标准输入文件、标准输出文件和标准错误文件的打开可以直接使用。

2、文件的关闭

  • 文件操作完成后,必须要将文件关闭,使缓冲区的数据能够全部存入文件
  • 关闭文件函数为fclose(),其函数原型为:int fclose(FILE *stream);,若其成功关闭了文件,则返回0值,否则返回非0值

三、读写函数

1、fputc函数和fgetc函数

  • fputc函数

    • 该函数将一个字符写到指定的文件中,其函数原型为:int fputc(char ch, FILE *fp),调用格式为fputc(ch, fp);
      其中ch是待输入的字符变量,fp是文件指针,将字符ch写入fp所指的文件中去,成功就返回写入字符的ASCII代码值,失败时返回EOF,即-1。
    • 被写入的文件必须是写、读写或追加方式打开的
    • 在文件内部有个位置指针,用来指向文件当前读写字节。每读写一次,该指针向后移动。
      #include <stdio.h>
      
      int main()
      {
          FILE *fp;
          char ch, file_name[10];
      
          gets(file_name);
      
          if ((fp = fopen(file_name, "w")) == NULL)		//打开文件
          {
              printf("can not open this file\n");
              return 0;										//终止程序
          }
      
          for (; (ch = getchar()) != '@'; )
              fputc(ch, fp);								//输入字符到fp
      
          fclose(fp);										//关闭文件
      
          return 0;
      }
      
  • fgetc函数

    • 从指定文件每次读取一个字符,其函数原型为:int fgetc(FILE *fp);,其调用格式为: c = fgetc(fp);如果调用成功,就把字符的ASICC码赋予c,c为int型,错误则返回EOF。

    • 使用fgetc函数读取一个字符后,文件内部指针向后移动一字节。

      #include <stdio.h>
      
      int main()
      {
          FILE *fp;
          char ch;
          fp = fopen("C:\\Users\\di\\text.txt", "r");			//打开文件
      
          if (fp == NULL)
          {
              printf("无法打开文件");
      
              return 0;
          } 
          
      
          while ((ch = fgetc(fp)) != EOF)
          {
              putchar(ch);					//顺序读入并显示
          }
      
          fclose(fp);
          return 0;
      }
      

2、fputs函数和fgets函数

  • fputs函数

    • 将一个字符串写到文件中,其函数原型为:int fputs(char *str, FILE *fp);,调用格式为:fputs(str, fp);
    • 正常时返回字符串,否则返回EOF。
  • fgets函数

    • 从文件中读取一个字符串,并存在字符指针所指的内存中,其函数原型为:char *fgets(char *str, int n, FILE *fp);其调用格式为:fgets(str, n, fp)
    • fp是文件指针,str是一个字符指针或者字符数组,n是字符的个数。
    • 从fp所指的文件中,每次读取n-1个字符,因为最后一个是'\0'。此函数调用出错时返回NULL
  • #include <stdio.h>
    #include <string.h>
    
    int main()\
    {
        FILE *fp;
        char file_name[30], str[81];
    
        printf("输入文件名:");
    
        gets(file_name);		//从键盘输入文件名
    
        fp = fopen(file_name, "a");			
    
        if (fp == NULL)
        {
            printf("该文件不存在。");
            return 0;
        }
    
        printf("请输入一个字符串:");
        
        gets(str);			//从键盘输入字符串
        fputs(str, fp);		//存入指定文件
        fclose(fp);
    
        fp = fopen(file_name, "r");		
    
        if (fp == NULL)
        {
            printf("该文件不存在。");
            return 0;
        }
    
        fgets(str, 81, fp);		//读取文本
        puts(str);			//输出屏幕
        fclose(fp);
    
        return 0;
    }
    

3、fread函数和fwrite函数

  • fread函数

    • 从文件中读取一段数据,函数原型为:int fread(char *buf, int size, int n, FILE *fp);调用格式为:fread(buf, size, n, fp);
    • buf是一个用来指向数据块在内存中的起始地址,size表示一个数据项的字节数,n表示读取n个数据项,fp则是文件指针。
    • 调用不成功则返回0,成功则返回数据项个数。
  • fwrite函数

    • 将一组数据写入文件,其函数原型为:int fwrite(char *buf, int size, int n, FILE *fp);,调用格式为:fwrite(buf, size, n, fp);
    • 和fread一样。。。。
  • 这俩函数一般用于二进制文件的读写

    //将两个学生的数据写入磁盘中,在读取,显示在屏幕上
    #include <stdio.h>
    
    struct stu			//定义学生数据
    {
        char name[20];
        int number;
        int age;
        char addr[15];
    }boy1[2], boy2[2], *pp, *qq;
    
    int main()
    {
        FILE *fp;
        int i;
        pp = boy1;
        qq = boy2;
        fp = fopen("C:\\Users\\di\\student", "wb+");		//打开文件并读写追加数据
    
        if (fp == NULL)
        {
            printf("无法打开文件。");
            return 0;
        }
    
        for (i = 0; i < 2; i++, pp++)			//输入学生数据
        {
            scanf("%s%d%d%s", pp -> name, &pp -> number, &pp -> age, pp -> addr);
        }
    
        pp = boy1;			//使pp重新指向开头
    
        fwrite(pp, sizeof(struct stu), 2, fp);		//将数据写入磁盘
        rewind(fp);									//使指针fp返回开头
        fread(qq, sizeof(struct stu), 2, fp);		//从磁盘读取数据到qq上
    
        printf("\n\nname\tnumber        age      addr\n");
    
        for (i = 0; i < 2; i++, qq++)				//打印数据
        {
            printf("%s\t%5d%7d       %s\n", qq -> name, qq -> number, qq -> age, qq -> addr);
        }
    
        fclose(fp);		//关闭文件
    
        return 0;
    }
    

4、fscanf函数和fprintf函数

  • fscanf函数:和scanf函数作用类似,从文件中读取数据,然后赋值:fscanf(fp, "格式控制字符串", 输出列表);
  • fprintf函数:和printf函数作用类型,输出列表的值,然后打印到文件中fprintf(fp, "格式控制字符", 输出列表);

四、文件的定位和随机读写

1、文件的定位

  • rewind函数:将fp指针重新回到文件开头位置,调用格式为:rewind(fp);
  • ftell函数:用来得到文件当前位置,调用格式为:i = ftell(fp);
  • fseek函数
    • 用来移动文件的位置指针,调用格式为:feek(fp, offset, origin);
    • fp是文件指针;offset为偏移量,表示相对起始点向后移动的字节数,一般是长整型数据;origin为起始点,规定的起始点有三种:文件首,数字表示为0当前位置,数字表示为1文件末尾,数字表示为2

2、文件的随机读写

  • 由于一般是读写一个数据块,因此常用fread和fwrite函数。

  • //将学生数据随机写入磁盘中
    #include <stdio.h>
    
    struct stu			//设定学生数据
    {
        char name[10];
        int number;
        int age;
        char addr[15];
    }boy;
    
    int main()
    {
        FILE *fp;			
        fp = fopen("c:\\Users\\di\\stu_list.txt", "ab+");		//打开并追加二进制文件
    
        if (fp == NULL)
        {
            printf("无法打开文件:");
            return 0;
        }
    
        printf("请输入学生学号1到5,0结束输入:");		//输入学生学号
        scanf("%d", &boy.number);
    
        while (boy.number != 0)
        {
            printf("请输入名字、年龄、地址:\n");
            scanf("%s%d%s", boy.name, &boy.age, boy.addr);
    
            fseek(fp, (boy.number - 1) * sizeof(struct stu), 0);		//将文件指针移动到相应位置
            fwrite(&boy, sizeof(struct stu), 1, fp);		//把学生数据写入文件
    
            printf("请输入学号:");
            scanf("%d", &boy.number);
        }
    
        fclose(fp);
    
        return 0;
    }
    

五、文件出错检测

  • ferror函数:用来检测读写时是否出错,其调用格式为:ferror(fp);,返回值为0,表示未出错,非零值表示出错。
    • 每次调用输入输出函数均会产生一个新的ferror()的函数值,因此在每次调用后应立即检查,否则检查信息会丢失。
    • 在执行fopen()函数时,ferror()的值会变成0;
  • feof函数:判断文件是否处于文件结束位置,调用格式为:feof(fp);,如果函数返回值为0,表示没有处于文件结束处;
  • clearerr函数:清除出错标志和文件结束标志,它将文件错误标志和文件结束标志的值设为0,调用格式为:clearerra(fp);

二、学习心得

之前学c的时候在想,我写这些程序怎么放到文件里?学到这就大概知道怎么一回事了。。。

历经一个多月,总算把c语言基础的这些东西学完了,之后我就继续学数据结构与算法喽。

标签:fp,文件,函数,记录,int,C语言,学习,FILE,指针
From: https://www.cnblogs.com/dragon-dai/p/17280509.html

相关文章

  • 学习httprunner遇到的问题记录
    今天研究httprunner遇到了几个问题1.问题1:最新的版本4.3.0已经舍弃了locusts,har2case这两个东西导致运行的时候,出现har2case不是内部命令一开始以为是没有配置环境变量我后面卸载改成3.1.4解决了4.3.0  明显可以在上图中,发现hmark,hrun,httprunner是还有的,但是最新的版......
  • Elasticsearch 学习-Elasticsearch进阶-索引,文档,字段,映射,分片,副本,分配,系统架构,分片控
    Elasticsearch学习-Elasticsearch进阶4.1核心概念4.1.1索引(Index)​ 一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母),并且当我们要对这个......
  • springboot学习笔记1-基本介绍
    springboot基本介绍官方文档什么是springbootspringboot可以轻松创建独立的、生产级的基于spring的应用程序springboot直接嵌入tomcat、jetty、或undertow,无须打war包,可以直接运行springboot应用程序quickstartforspringbootdemo需求说明:quickstart创建......
  • Elasticsearch 学习-Linux单机和集群安装
    Elasticsearch学习-Linux单机和集群安装3.3linux集群安装3.3.1软件下载软件下载地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-8-03.3.2软件安装1)解压软件将下载的软件解压缩#解压缩tar-zxvfelasticsearch-7.8.0-linux-x86_64.tar......
  • VUE2.0 学习 第一组
    本笔记主要参考菜鸟教程和官方文档编写。 1.对于Vue2.0来说每个vue应用都需要实例化vue来实现。   varvm=newVue({//选项}) 2.首先,DOM是一种api,它可以动态地访问程序和脚本,更新其内容、结构和文档,我认为符合这类功能的都可以叫dom,其次,每一个DOM元素的id(......
  • C语言逆向——如何寻找main入口,一个反汇编成C的实战练习
    第二节2.3找程序的入口原文:https://www.showdoc.com.cn/fengxin1225/7054696489361869控制台应用程序的main函数入口在OD中找到以上其他中的函数,然后跟着3个参数的CALL就是main例:———————————————————- 第二节2.4.1逆向并还原为C代码(网上解答)......
  • qmake学习
    在Qt的.pro文件中,有许多变量可以用于配置和管理项目的构建过程以下是Qt中常用的.pro变量及其说明:SOURCES:指定项目源代码文件的名称和路径,以空格分隔HEADERS:指定项目头文件的名称和路径,以空格分隔FORMS:指定QtDesignerUI文件的名称和路径,以空格分隔RESOURCES:指定Qt资源文件的名称......
  • 计网学习笔记五 wireless && mobile networks
    老师把无线网络用一节课一遍过了…感觉没能学透,便课后自己总结,看书,找资料补充,把无线网络大概摸了个七七八八。虽然不算精细,但还能看!内容包括WLAN总概,WiFi—WLAN的实现,802.11规定的帧结构,以及蜂窝网络。强烈推荐一本书:《802.11WirelessNetworks:TheDefinitiveGuide》,2ndEd......
  • .net reactor 学习系列(五)---.net reactor针对De4Dot脱壳工具的应对
     De4Dot是一个专门反混淆.net程序的一个工具,支持对于以下工具混淆过的代码的清理:Agile.NET(akaCliSecure)Babel.NETCodeFortCodeVeilCodeWallCryptoObfuscatorDeepSeaObfuscatorDotfuscator.NETReactorEazfuscator.NETGoliath.NETILProtectorMaxtoCodeMPRESSRummageSkater.N......
  • 记录一下最近做的从PVE到ESXi的虚拟机迁移操作
    PVE版本是ProxmoxVirtualEnvironment7.1-4ESXi版本是6.5待迁移的虚拟机是Debian111,先在PVE的虚拟机中进行BackupCompression选的ZSTD,Mode选的是Stop2,备份完成之后,SSH到PVE主机进行操作sshroot@PVE_HOST_IPPVE内置的备份可以生成VMA文件(ProxmoxVirtu......