百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

读书笔记之C Primer Plus 6

liebian365 2024-11-21 17:35 24 浏览 0 评论

为什么阅读《C Primer Plus》第六版

准备好好研究下redis源码,但是很久没用c语言写代码了,平时工作主要用java和js。
所以准备重新阅读学习下c语言经典书籍:C Primer Plus。
更好地阅读redis源码。


第13章 文件输入/输出

文件是当今计算机系统不可或缺的部分。文件用于存储程序、文档、数据、书信、表格、图形、照片、视频和许多其他种类的信息。

什么是文件

文件通常是在磁盘或固体硬盘上的一段已命名的存储区。
C提供两种文件模式:文本模式和二进制模式。

文本模式和二进制模式

所有文件的内容都以二进制形式存储。

  • 文本模式:如果文件最初使用二进制编码的字符(ASCII或Unicode)表示文本,该文件就是文本文件。
  • 二进制模式:如果文件中的二进制值代表机器语言代码或数值数据或图片或音乐编码,该文件就是二进制文件。
  • 在二进制模式中,程序可以访问文件的每个字节。
  • 在文本模式中,程序所见的内容和文件的实际内容不同。
  • 程序以文本模式读取文件时,把本地环境表示的行末尾或文件结尾映射为C模式。(比如\r转换成\n)
  • 除了以文本模式读写文本文件,还能以二进制模式读写文本文件

I/O的级别

  • 底层I/O(low-level I/O)使用操作系统提供的基本I/O服务
  • 标准高级I/O(standard high-level I/O)使用C库的标准包和stdio.h头文件定义
  • 标准高级I/Os比底层I/O容易跨平台移植。标准io使用缓冲区,底层io需要自己处理缓存。

标准文件

C程序会自动打开3个文件,它们被称为标准输入(standard input)、标准输出(standard output)和标准错误输出(standard error output)。
在默认情况下,标准输入是系统的普通输入设备,通常为键盘;标准输出和标准错误输出是系统的普通输出设备,通常为显示屏。

标准I/O

/* count.c -- 使用标准 I/O */
#include <stdio.h>
#include <stdlib.h>    // 提供 exit()的原型

int main(int argc, char *argv [])
{
     int ch;          // 读取文件时,存储每个字符的地方
     FILE *fp;        // “文件指针”
     unsigned long count = 0;
     if (argc != 2)
     {
          printf("Usage: %s filename\n", argv[0]);
          exit(EXIT_FAILURE);
     }
     if ((fp = fopen(argv[1], "r")) == NULL)
     {
          printf("Can't open %s\n", argv[1]);
          exit(EXIT_FAILURE);
     }
     while ((ch = getc(fp)) != EOF)
     {
          putc(ch, stdout);    // 与 putchar(ch); 相同
          count++;
     }
     fclose(fp);
     printf("File %s has %lu characters\n", argv[1], count);
     return 0;
}
  • return 0 和 exit 区别。

fopen函数

  • 函数声明在stdio.h中
  • 第一个参数:打开文件的包含该文件名的字符串地址。
  • 第二个参数:打开文件的模式,r=读模式,w=写模式
  • x模式:x模式的独占特性使得其他程序或线程无法访问正在被打开的文件
  • 成功打开文件后,fopen()将返回文件指针。
  • 文件指针不指向实际的文件,它指向一个包含文件信息的数据对象,其中有缓冲区信息。

getc和putc

  • ch = getchar(); 从标准输入中获取一个字符;
  • ch = getc(fp); 从fp指向的文件中获取一个字符;
  • putc(ch,fpout); 把字符ch放入FILE指针fpout指定的文件中;
  • 都定义在stdio.h中

文件结尾

返回一个特殊值EOF代表文件末尾

int ch;
FILE * fp;
fp = fopen("wacky.txt", "r");
while (( ch = getc(fp)) != EOF)
{
     putchar(ch);    //处理输入
}

fclose函数

  • 成功返回0
  • 失败返回EOF
  • 磁盘已满、移动磁盘移除或出现io错误,都会失败
if (fclose(fp) != 0)
     printf("Error in closing file %s\n", argv[1]);

指向标准文件的指针

stdio.h头文件把3个文件指针与3个标准文件相关联,C程序会自动打开这3个标准文件。

  • 标准输入 stdin
  • 标准输出 stdout
  • 标准错误 stderr

fprintf和fscanf

文件I/O函数fprintf()和fscanf()函数的工作方式与printf()和scanf()类似,区别在于前者需要用第1个参数指定待处理的文件。
都把FILE指针作为第一个参数,而不是最后一个参数。

fprintf(fp,"%s\n",words);
fscanf(fp,"%s",words);

fgets和fputs

  • fgets第一个参数表示存储输入位置的地址(char* 类型);
  • fgets第二个参数事一个整数,待输入字符串的大小;
  • fgets第三个参数是文件指针;
  • fgets(buf,STLEN,fp);
  • fgets读取输入直到第一个换行符的后面,或读到文件结尾,或者读取STLEN-1个字符;
  • 然后fgets在末尾添加一个空字符使之成为一个字符串;
  • fputs第一个参数是字符串的地址;
  • fputs第二个参数事文件指针;
  • 由于fgets保留了换行符,fputs就不会再添加换行符;

随机访问fseek和ftell

  • fseek第一个参数是FILE指针,fopen返回的文件指针
  • fseek第二个参数是编移量,必须是long类型的值,正(前移),负(后移)或0(保持不动)
  • fseek第三个参数事模式,该参数确定起始点,
  • stdio.h常量-> SEEK_SET文件开始处、SEEK_CUR当前闻之、SEEK_END文件末尾,旧的实现对应0L、1L、2L
  • ftell函数返回类型long,返回指向文件的当前位置距文件开始处的字节数;
  • last = ftell(fp);
fseek(fp,0L,SEEK_SET); //定位至文件开始处
fseek(fp,10L,SEEK_SET);//定位至文件中的第10个字符
fssek(fp,2L,SEEK_CUR);//从文件当前位置前移2个字节
fseek(fp,0L,SEEK_END);//定位至文件结尾
fseek(fp,-10L,SEEK_END);//从文件结尾处回退10个字节;

fgetpos和fsetpos

  • 不使用long类型,使用新类型:fpos_t文件定位类型
//调用该函数时,它把fpos_t类型的值放在pos指向的位置上,该值描述了文件中的当前位置距文件开头的字节数。如果成功,fgetpos()函数返回0;如果失败,返回非0。
int fgetpos(FILE * restrict stream,fpos_t * restrict pos);
//调用该函数时,使用pos指向位置上的fpos_t类型值来设置文件指针指向偏移该值后指定的位置。如果成功,fsetpos()函数返回0;如果失败,则返回非0。fpos_t类型的值应通过之前调用fgetpos()获得。
int fsetpos(FILE *stream,const fpos_t *pos);

int ungetc(int c, FILE *fp)函数

int ungetc()函数把c指定的字符放回输入流中。

int fflush()函数

int fflush()函数

调用fflush()函数引起输出缓冲区中所有的未写入数据被发送到fp指定的输出文件。这个过程称为刷新缓冲区。

int setvbuf()函数

int setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size);

setvbuf()函数创建了一个供标准I/O函数替换使用的缓冲区。在打开文件后且未对流进行其他操作之前,调用该函数。指针fp识别待处理的流,buf指向待使用的存储区。

fwrite和fread

  • fwrite把二进制数据写入文件
  • fwrite返回size_t类型
  • fread()函数接受的参数和fwrite()函数相同。
  • 在fread()函数中,ptr是待读取文件数据在内存中的地址,fp指定待读取的文件。
size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb,FILE * restrict fp);
size_t fread(void * restrict ptr, size_t size, size_t nmemb,FILE * restrict fp);

读书总结

这章仔仔细细看了两遍,对c的标准I/O有了清晰的认识,不像java的IO这么多。java的io虽然灵活,但略显繁琐。

相关推荐

go语言也可以做gui,go-fltk让你做出c++级别的桌面应用

大家都知道go语言生态并没有什么好的gui开发框架,“能用”的一个手就能数的清,好用的就更是少之又少。今天为大家推荐一个go的gui库go-fltk。它是通过cgo调用了c++的fltk库,性能非常高...

旧电脑的首选系统:TinyCore!体积小+精简+速度极快,你敢安装吗

这几天老毛桃整理了几个微型Linux发行版,准备分享给大家。要知道可供我们日常使用的Linux发行版有很多,但其中的一些发行版经常会被大家忽视。其实这些微型Linux发行版是一种非常强大的创新:在一台...

codeblocks和VS2019下的fltk使用中文

在fltk中用中文有点问题。英文是这样。中文就成这个样子了。我查了查资料,说用UTF-8编码就行了。edit->Fileencoding->UTF-8然后保存文件。看下下边的编码指示确...

FLTK(Fast Light Toolkit)一个轻量级的跨平台Python GUI库

FLTK(FastLightToolkit)是一个轻量级的跨平台GUI库,特别适用于开发需要快速、高效且简单界面的应用程序。本文将介绍Python中的FLTK库,包括其特性、应用场景以及如何通过代...

中科院开源 RISC-V 处理器“香山”流片,已成功运行 Linux

IT之家1月29日消息,去年6月份,中科院大学教授、中科院计算所研究员包云岗,发布了开源高性能RISC-V处理器核心——香山。近日,包云岗在社交平台晒出图片,香山芯片已流片,回片后...

Linux 5.13内核有望合并对苹果M1处理器支持的初步代码

预计Linux5.13将初步支持苹果SiliconM1处理器,不过完整的支持工作可能还需要几年时间才能完全完成。虽然Linux已经可以在苹果SiliconM1上运行,但这需要通过一系列的补丁才能...

Ubuntu系统下COM口测试教程(ubuntu port)

1、在待测试的板上下载minicom,下载minicom有两种方法:方法一:在Ubuntu软件中心里面搜索下载方法二:按“Ctrl+Alt+T”打开终端,打开终端后输入“sudosu”回车;在下...

湖北嵌入式软件工程师培训怎么选,让自己脱颖而出

很多年轻人毕业即失业、面试总是不如意、薪酬不满意、在家躺平。“就业难”该如何应对,参加培训是否能改变自己的职业走向,在湖北,有哪些嵌入式软件工程师培训怎么选值得推荐?粤嵌科技在嵌入式培训领域有十几年经...

新阁上位机开发---10年工程师的Modbus总结

前言我算了一下,今年是我跟Modbus相识的第10年,从最开始的简单应用到协议了解,从协议开发到协议讲解,这个陪伴了10年的协议,它一直没变,变的只是我对它的理解和认识。我一直认为Modbus协议的存...

创建你的第一个可运行的嵌入式Linux系统-5

@ZHangZMo在MicrochipBuildroot中配置QT5选择Graphic配置文件增加QT5的配置修改根文件系统支持QT5修改output/target/etc/profile配置文件...

如何在Linux下给zigbee CC2530实现上位机

0、前言网友提问如下:粉丝提问项目框架汇总下这个网友的问题,其实就是实现一个网关程序,内容分为几块:下位机,通过串口与上位机相连;下位机要能够接收上位机下发的命令,并解析这些命令;下位机能够根据这些命...

Python实现串口助手 - 03串口功能实现

 串口调试助手是最核心的当然是串口数据收发与显示的功能,pzh-py-com借助的是pySerial库实现串口收发功能,今天痞子衡为大家介绍pySerial是如何在pzh-py-com发挥功能的。一、...

为什么选择UART(串口)作为调试接口,而不是I2C、SPI等其他接口

UART(通用异步收发传输器)通常被选作调试接口有以下几个原因:简单性:协议简单:UART的协议非常简单,只需设置波特率、数据位、停止位和校验位就可以进行通信。相比之下,I2C和SPI需要处理更多的通...

同一个类,不同代码,Qt 串口类QSerialPort 与各种外设通讯处理

串口通讯在各种外设通讯中是常见接口,因为各种嵌入式CPU中串口标配,工业控制中如果不够还通过各种串口芯片进行扩展。比如spi接口的W25Q128FV.对于软件而言,因为驱动接口固定,软件也相对好写,因...

嵌入式linux为什么可以通过PC上的串口去执行命令?

1、uboot(负责初始化基本硬bai件,如串口,网卡,usb口等,然du后引导系统zhi运行)2、linux系统(真正的操作系统)3、你的应用程序(基于操作系统的软件应用)当你开发板上电时,u...

取消回复欢迎 发表评论: