C语言KR圣经笔记 7.1标准输入和输出 7.2格式化输出-printf

第七章 输入和输出


输入和输出功能并不是 C 语言本身的一部分,故到目前为止,本书都没有对其着重说明。然而,程序与其环境之间交互的方式,比书中之前所展示的更为复杂。本章我们会详描述标准库,即一系列为 C 程序提供输入输出、字符串处理、内存管理、数学例程及其他各种服务的函数。

ANSI 标准精确定义了这些库函数,因此在任何有 C 语言的系统中也都有这些标准库函数,并且是互相兼容的。如果一个程序只使用了标准库提供的功能来与系统进行交互,那么这个程序不用修改就可以从一个系统移植到另一个系统。

库函数的特性在超过一打的头文件中指定【C89时是15个,C11时将近30个】;有些我们已经见过,如 <stdio.h>、<string.h> 和 <ctype.h>。本章不会介绍库的全部内容,因为我们更感兴趣的是如何使用库来写 C 程序。库的细节在附录 B 描述。

7.1 标准输入和输出

如第一章所述,库函数实现了文本输入输出的简单模型。文本流包含了行的序列;每行以一个换行字符结束。如果系统不是按这个方式操作的,库会采取必要的措施,使其看起来像是如此。例如,库可以在输入中把回车符加换行符转换成换行符,并在输出中做反向的转换。

最简单的输入方式是使用 getchar 从“标准输入”(通常是键盘)中每次读一个字符:

int getchar(void)

getchar 每次被调用时返回下一个输入字符,若遇到文件结尾时返回 EOF。符号常量 EOF 在<stdio.h> 中定义。通常其值为 -1,但写判断时应该用 EOF,这样才不依赖特定的值。

在很多环境下,使用输入重定向符号 < ,能把键盘替换成文件:如果程序 prog 使用了 getchar,则如下命令行

prog <infile

使 prog 改从 infile 中读取字符。prog 程序本身不感知输入的切换;特别注意 “infile” 字符串并不包含在 argv 的命令行参数列表中。如果通过管道机制使输入来自另一个程序,输入切换也是不可见的:在某些系统上,命令行

otherprog | prog

运行 otherprog 和 prog 两个程序,并把 otherprog 的标准输出通过管道送到 prog 的标准输入中。

函数

int putchar(int)

用于输出:putchar(c) 将 c 输出到 “标准输出”中,默认为屏幕。putchar 返回已输出的字符,若遇到错误则返回 EOF。和输入一样,通常可以使用 >filename 将输出重定向到文件中:如果 prog 使用了 putchar,则

prog >outfile

把标准输出写到 outfile 文件。如果系统支持管道机制,则

prog | anotherprog

把 prog 的标准输出送到 anotherprog 的标准输入中。

printf 产生的输出也是送往标准输出。我们可以交替调用putchar 和 printf ——输出显示的顺序就是调用的顺序。

每个引用标准输入输出库函数的源文件,都必须在首次引用之前包含下面这行

#include <stdio.h>

当文件名用尖括号括起来时,会在一些标准的文件路径集合中搜索头文件(例如,在UNIX系统中,通常在 /usr/include 目录下)。


很多程序只读一个输入流且只写一个输出流;对这样的程序,使用 getchar,putchar 和 printf 来做输入输出也许就完全够了,而对入门来说是肯定够的。如果使用重定向把一个程序的输出连接到下一个程序的输入,则更是如此。例如,考虑这个把输入转换成小写的程序 lower:

#include <stdio.h>
#include <ctype.h>main()    /* lower:把输入转换成小写 */
{int c;while((c = getchar()) != EOF)putchar(tolower(c));return 0;
}

tolower 函数定义在 <ctype.h> 中;它将一个大小字母转换成小写,而其他字符则原封不动地返回。我们前面提到过,如 <stdio.h> 中的 getchar 和 putchar 以及 <ctype.h> 中的 tolower,这样的“函数” 通常是宏定义,因此可以避免对每个字符做函数调用带来的开销。我们将在8.5节展示如何做到这一点。无论在特定的机器上 <ctype.h> 中的函数是如何实现的,标准库都对使用这些函数的程序屏蔽了具体的字符集。

练习7-1、写一个程序,可以将大写转换成小写、或将小写转换成大写,具体要做哪种转换,是根据该程序被调用时的名字(通过 argv[0] 获取)来决定的。

7.2 格式化输出——printf

输出函数 printf 将内部的值转换为字符串。在前面的章节中我们不太正式地使用了 printf。本节覆盖了它最典型的用法,但不是全部内容;完整内容参见附录 B。

int printf(char *format, arg1, arg2, ...)

printf 在 format 的控制下,对其参数做转换、格式化,并打印到标准输出。它返回已打印的字符数量。

格式化字符串包含两种对象:拷贝到输出流的普通字符,以及转换规格:每个转换规格都会使printf 的下一个参数被转换并打印出来。每个转换规格以一个 % 开头,并以一个转换字符结尾。在 % 和转换字符之间,依次可以为:

  • 减号,表明被转换的参数要左对齐。
  • 数字,指定了最小的域宽度。被转换的参数会打印在最小为该宽度的域中。若宽度不够,则会在左边填充到足够的宽度。(如果指定了左对齐,则在右边填充)
  • 点号,分隔域宽度和精度。
  • 数字,表示精度,有三种情况。对于字符串:指定了字符串中最多打印的字符数。对于浮点数:小数点后最多的位数。对于整数:最少的位数。
  • 字母 h 或 l,用于整数打印,前者表示打印为 short,后者表示打印为 long

转换字符见表 7-1。若 % 之后不是转换说明,则该行为是未定义的。

表7-1 基本的 printf 转换说明
字符类型打印为
d,iint十进制数
oint无符号八进制数(无前导0)
x,Xint无符号十六进制数(无前导0x或0X),使用abcdef或ABCDEF表示 10到15。
uint无符号十进制数
cint单个字符
schar *打印字符串中的字符,直到遇到'\0',或者精度给出的字符数。
fdouble[-]m.dddddd,其中d的数量由精度决定(默认为6)
e,Edouble[-]m.dddddde+-xx 或 [-]m.ddddddE+-xx,其中d的数量由精度决定(默认为6)
g,Gdouble如果幂小于-4或大等于精度时,使用 %e或%E;否则使用 %f。末尾的0和结尾的小数点不打印。
pvoid *指针(由具体实现来决定如何呈现)
%无转换参数打印%

宽度和精度可以指定为 * ,这种情况下它的值是通过转换下一个参数(必须为int)计算出来的。例如,要在字符串 s 中最多打印 max 个字符,写为:

printf("%.*s", max, s);

大部分的格式转换已经在前面的章节中说明过了。不过还有字符串的精度没讲过。下表显示了不同规格下打印 “hello, world”(12个字符)的效果。我们在两边加上了冒号,以便读者看清其范围:

警告:printf 使用它的首个参数来确定其后跟着多少个参数,以及这些参数各自的类型。如果没有足够的参数,或者类型错误,则 printf 会被搞混,而你的代码将得到错误的结果。还应该注意下面两个调用的不同之处:

printf(s);          /* 若s包含%则有问题 */
printf("%s", s);    /* 安全 */


sprintf 函数做与 printf 同样的转换,不过它把输出储存到一个字符串里:

int sprintf(char *string, char *format, arg1, arg2, ...)

sprintf 也是同样根据 format 将参数 arg1, arg2 等格式化,不过是将结果保存在 string 里面,而不是标准输出;string 必须足够大以接收这个结果。

练习7-2、写个程序,以合理的方式打印任意输入。最低限度下,它能够按本地习惯用八进制或十六进制打印非图形字符,且能够断开长文本行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/452981.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion 模型下载:国风3 GuoFeng3

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十推荐提示词下载地址模型介绍 欢迎使用GuoFeng3模型 - 这是一个中国华丽古风风格模型,也可以说是一个古风游戏角色模型,具有2.5D的质感。 条目内

数字人客服技术预研

技术洞察 引言 在当今数字化时代&#xff0c;不断进步和创新的人工智能&#xff08;AI&#xff09;技术已经渗透到各行各业中。随着AI技术、大模型技术逐步发展&#xff0c;使得数字人的广泛应用成为可能&#xff0c;本文将跟大家一起探讨AI数字人客服的概念、优势、应用场景…

【Java八股文面试系列】JVM-内存区域

目录 Java内存区域 运行时数据区域 线程独享区域 程序计数器 Java 虚拟机栈 StackFlowError&OOM 本地方法栈 线程共享区域 堆 GCR-分代回收算法 字符串常量池 方法区 运行时常量池 HotSpot 虚拟机对象探秘 对象的创建 对象的内存布局 句柄 Java内存区域 运…

使用WPS制作三线表

点击边框和底纹点击1、2、3、4并且应用于表格点击确定 再次选中表格点击右键表格属性选择边框和底纹 选中表格第一行右键点击表格属性选择边框和底纹 如果表格中存在虚线

左旋字符串的三种方法,并判断一个字符串是否为另外一个字符串旋转之后的字符串。(strcpy,strncat,strcmp,strstr函数的介绍)

一. 实现一个函数&#xff0c;可以左旋字符串中的k个字符。 例如&#xff1a; ABCD左旋一个字符得到BCDA ABCD左旋两个字符得到CDAB 通过分析&#xff0c;可以知道实际的旋转次数&#xff0c;其实是k%&#xff08;字符串长度&#xff09;。假设一个字…

Unity_修改天空球

Unity_修改天空球 Unity循序渐进的深入会发现可以改变的其实很多&#xff0c;剖开代码逻辑&#xff0c;可视化的表现对于吸引客户的眼球是很重要的。尤其对于知之甚少的客户&#xff0c;代码一般很难说服客户&#xff0c;然表现确很容易。 非代码色彩通才&#xff0c;持续学习…

PyTorch 2.2 中文官方教程(十七)

&#xff08;Beta&#xff09;使用缩放点积注意力&#xff08;SDPA&#xff09;实现高性能 Transformer 原文&#xff1a;pytorch.org/tutorials/intermediate/scaled_dot_product_attention_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 注意 点击这…

《动手学深度学习(PyTorch版)》笔记7.2

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过&…

前端面试题——Vue的双向绑定

前言 双向绑定机制是Vue中最重要的机制之一&#xff0c;甚至可以说是Vue框架的根基&#xff0c;它将数据与视图模板相分离&#xff0c;使得数据处理和页面渲染更为高效&#xff0c;同时它也是前端面试题中的常客&#xff0c;接下来让我们来了解什么是双向绑定以及其实现原理。…

笔记本电脑的WIFI模块,突然不显示了,网络也连接不上

问题复现&#xff1a; 早上&#xff0c;在更新完笔记本电脑的系统之后&#xff0c;连网之后&#xff0c;网络突然直接断开&#xff0c;一查看&#xff0c;WiFi模块居然不见了&#xff0c;开机重启也是如此&#xff0c;这种情况常常出现在更新系统之后&#xff0c;WiFi模块驱动就…

hdfs datanode数据分布不均调整(hdfs balancer )

Hadoop集群Datanode数据倾斜&#xff0c;个别节点hdfs空间使用率达到95%以上&#xff0c;于是新增加了三个Datenode节点&#xff0c;由于任务还在跑&#xff0c;数据在不断增加中&#xff0c;这几个节点现有的200GB空间估计最多能撑20小时左右&#xff0c;所以必须要进行balanc…

【Elasticsearch】从入门到精通

目前java常见的针对大数据存储的方案并不多&#xff0c;常见的就是mysql的分库分表、es存储 这里偏向es存储方案&#xff0c;es不同的版本之间其实差异还挺大的&#xff0c;本篇博文版本Elasticsearch 7.14.0 Springboot整合Easy-Es Easy-Es官方文档 Elasticsearch的初步认识 …