1.5 C语言之字符输入输出

1.5 C语言之字符输入输出

  • 一、概述
  • 二、字符计数
  • 三、行计数
  • 四、单词计数
  • 五、练习

一、概述

字符文本流,是由多行字符构成的字符序列,而每行字符都由0个或多个字符组成,行末是一个换行符。
标准库提供的输入输出模型,用于读取文本内容到内存中(输入),将内存中的字符写入文件中(输出)
标准库提供了一次读写一个字符的功能,getchar(), putchar()

#include <stdio.h>
main()
{
	char c = getchar(); // 从文本流中读入下一个输入字符(从键盘输入),并将其结果值返回
	putchar(c); // 打印变量c
}

在这里插入图片描述
利用getchar和putchar写一个简单的例子:输入一个字符,将它复制到输出,循环往复,直到文件结束符(EOF)退出
基本思路:
输入一个字符
while(输入的字符不是文件结束符)
输出刚输入的字符
输入下一个字符

#include <stdio.h>
/*
   把输入复制到输出
*/
main()
{
	int c;
	while ((c = getchar()) != EOF)
	{
		putchar(c);
	}
}

关系运算符!=表示不等于
C语言中,在没有输入时,getchar将返回一个特殊值,这个特殊值与任何实际字符都不同,这个字符就是EOF(end of file),表示文字流(stream)的结尾。这里的文字流,可以是文件(file),也可以是标准输入(stdin)。EOF不是特殊字符,而是一个定义在头文件stdio.h的常量,一般等于-1。在windows下输入EOF需要输入CTRL+Z,在UNIX系统下输入EOF需要输入CTRL+D

二、字符计数

编写一个程序,统计总共输入了多少个字符

#include <stdio.h>
main()
{
	long count = 0;
	while (getchar() != EOF)
	{
		// ++ 执行加1操作,等同于 count = count + 1
		++count;
	}
	printf("%ld\n", count);
}

练习:使用for改写上面的程序

#include <stdio.h>
main()
{
	long count = 0;
	for (;getchar() != EOF; ++count)
		;// 注意这个分号必须得加,表示for的循环体语句
	printf("%ld\n", count);
}

三、行计数

编写一个程序,统计总共输入了多少行字符

#include <stdio.h>
main()
{
	int count=0, c;
	while ((c = getchar()) != EOF)
	{
	    // = 赋值,== 等于, '\n' 表示换行
		if (c == '\n')
		{
			++count;
		}
	}
	printf("%d\n", count);
}

需要注意的是,单引号中字符表示一个整型值,该值等于此字符在机器字符集中对应的数值,我们称之为字符常量。它只不过是小整型数的一种写法,比如,‘A’ 是一个字符常量:在ASCII字符集中其值为65,当然,用’A’比用65更具有表达性,且与具体的字符集无关。
在这里插入图片描述

	printf("%c\n", 'A');
	printf("%c\n", 'a');
	printf("%d\n", 'A');
	printf("%d\n", 'a');

练习:使用for改写上面的程序

#include <stdio.h>
main()
{
	int count=0, c;
	for(;(c=getchar())!=EOF;)
	{
		if (c == '\n')
		{
			++count;
		}
	}
	printf("%d\n", count);
}

四、单词计数

#include <stdio.h>
#define OUT_WORD 1 // 不在单词中,遇到空格、换行符、制表符,state设置成 OUT_WORD
#define IN_WORD 0  // 在单词中,遇到单词的第一个字符时,state设置成 IN_WORD,并进行单词计数

// 编写一个程序,统计输入行数(lines)、单词数(words)、字符数(charactors)
// 这里假定单词中不包含空格、换行符、制表符
main()
{
	
	int c, nl, nw, nc, state;
	state = OUT_WORD; // 初始值,不在单词中
	nl = nw = nc = 0; // 连续赋值,从右至左
	while ((c = getchar()) != EOF)
	{
		++nc; // 字符数
		if (c == '\n')
			++nl; // 行数
		// || 代表逻辑或,&&代表逻辑与,两个都是短路运算符,比如
		// a||b 当a条件为真,则整个表达式结果为真,则不再执行条件b
		// a&&b 当a条件为假,则整个表达式结果为假,则不再执行条件b
		if (c == ' ' || c == '\n' || c == '\t') 
			state = OUT_WORD;
		else if (state == OUT_WORD) {
			state = IN_WORD;
			++nw; // 单词数
		}
	}
	printf("行数:%d, 单词数:%d, 字符数:%d", nl, nw, nc);
}

五、练习

  1. 验证 getchar() != EOF 的值是0还是1
#include <stdio.h>
main()
{
	// 输入CTRL+Z, 0
	// 输入其他字符, 1
	printf("%d", getchar() != EOF);
}
  1. 编写一个打印EOF值的程序
#include <stdio.h>
main()
{
	printf("%d", EOF);
}
  1. 编写一个统计空格、制表符、换行符个数的程序
#include <stdio.h>
// 统计空格、制表符、换行符个数
main()
{
	long sc, tc, nc, c;
	sc = 0;
	tc = 0;
	nc = 0;
	while ((c = getchar()) != EOF)
	{
		if (c == ' ')
			++sc;
		if (c == '\t')
			++tc;
		if (c == '\n')
			++nc;
	}

	printf("%ld, %ld, %ld\n", sc, tc, nc);
}
  1. 编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替
#include <stdio.h>

// 编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替
// 关键思路:如何将连续的多个空格用一个空格代替?
// 假如有3个空格,那么只打印第1个即可,后面的2个空格全部舍弃
// 那么如果当前字符是空格的话,就得判断前面的字符是不是空格,如果是空格,当前空格舍弃;如果不是空格,说明不是连续空格,打印当前空格
// 那么既然可以只打印第1个,理论上当然也可以只打印最后1个空格
main()
{
	int c;
	// 上一个字符
	int lc = 's'; 
	while ((c = getchar()) != EOF)
	{
		if(c != ' ')
			putchar(c);
		// 如果上一个字符是空格,丢弃当前空格;如果上一个字符不为空格,那么输出当前空格
		if(c == ' ')
			if(lc != ' ')
				putchar(c);
		lc = c;
	}
}
#include <stdio.h>

// 编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替
// 那么既然可以只打印第1个,理论上当然也可以只打印最后1个空格
// 如果只打印第最后1个空格,什么时候打印呢,当它后面的字符不是空格时,打印
main()
{
	// 当前输入字符
	int c;
	// 上一个字符
	int lc = 's';
	while ((c = getchar()) != EOF)
	{
		if (c != ' ')
		{
			if (lc == ' ')
			{
				putchar(lc);
			}
			putchar(c);
		}
		lc = c;
	}
}

那么如果我不选择第1个和最后1个,可以吗?假定有n(0~n-1)个空格,从中选出1个,那么第1个和最后1个永远是最简单的情况
如果要从1~n-2中选一个打印,那么选吧,选哪一个呢,理论上当然也是可以的,只不过编码起来有些冗余。我不再做过多挣扎

  1. 编写一个将输入复制到输出的程序,并将其中的制表符替换成\t,把回车符替换为\b,把反斜杠替换为\。这样可以将制表符和回退符以可见的方式显示出来
#include <stdio.h>

// 编写一个将输入复制到输出的程序,
// 并将其中的制表符替换成\t,把回车符替换为\b,把反斜杠替换为\\。这样可以将制表符和回退符以可见的方式显示出来
main()
{
	// 当前输入字符
	int c;
	while ((c = getchar()) != EOF)
	{
		if (c == '\t')
			printf("\\t");
		else if (c == '\b')  // 存疑,回退符如何输入
			printf("\\b");
		else if (c == '\\')
			printf("\\\\");
		else 
			putchar(c);
					
	}
}
  1. 你准备如何测试单词计数程序?如果程序中存在错误,那么什么样的输入最有可能发现这类错误呢?
  • 常规测试,输入字符中包含单词、空格、制表符、回车进行测试
  • 边界条件最容易发现错误:比如
    • 没有输入
    • 没有单词,只有换行符
    • 没有单词,只有空格、制表符、换行符
    • 每个单词各占一行
    • 单词位于行首
    • 单词位于一串空格之后的情况
  1. 编写一个程序,以每行一个单词的形式打印其输入
#include <stdio.h>
#define OUT_WORD 1 // 不在单词中,遇到空格、换行符、制表符,state设置成 OUT_WORD
#define IN_WORD 0  // 在单词中,遇到单词的第一个字符时,state设置成 IN_WORD

//  编写一个程序,以每行一个单词的形式打印其输入
main()
{
	int c, state;
	state = OUT_WORD; // 初始值,不在单词中
	while ((c = getchar()) != EOF)
	{
		if (c == ' ' || c == '\n' || c == '\t') {
			if (state == IN_WORD) {
				state = OUT_WORD;
				putchar('\n'); // 单词结束
			}
		} else if (state == OUT_WORD) {
			state = IN_WORD;
			putchar(c); // 单词开始
		} else 
			putchar(c); // 单词除了首尾字符之外的其他字符
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

树状数组 / pbds解法 E2. Array Optimization by Deque

Problem - 1579E2 - Codeforces Array Optimization by Deque - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 树状数组解法 将 a i a_i ai​插入到队头&#xff0c;贡献为&#xff1a;原队列中所有比 a i a_i ai​小的数的数量将 a i a_i ai​插入到队尾&#xff0c;贡献为&a…

JPA 自关联 设置单向多对一

Spring boot 3 JPA中&#xff0c;遇到一个需求&#xff0c;建一个数据字典表&#xff1a; Dictionary&#xff0c;存放两级数据&#xff0c;第一级为字典项目&#xff0c;第二级为项目内容&#xff0c;查询时要把parent_id对应父项的名称也一起查出来&#xff0c;返回前端。 …

python类和对象

1.使用对象组织数据 class Student:nameNone #记录名字 stu1Student() #创建对象 stu1.name"abc" #为对象属性赋值2.类的定义和使用 2.1成员方法的定义语法 传参的时候self是透明的&#xff0c;不用管 class Stu:nameNonedef sayHi(self):print(f"你好&#x…

Kotlin应用——使用kt进行web开发 使用h2database进行初始化数据库 mybatis-plus使用

Kotlin 是一门现代但已成熟的编程语言&#xff0c;旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作&#xff0c;并提供了多种方式在多个平台间复用代码&#xff0c;以实现高效编程。 kt入门的合集文章如下&#xff1a; Kotlin学习——kt入门合集博客 &…

realname,soname和linkname

背景 当在看/lib下的一些文件时候&#xff0c;我们发现几乎都是三个动态库文件&#xff0c;为啥&#xff1f; 分析 当我发布一个动态库的时候&#xff0c;比如版本是maj.min.patch&#xff08;10.2.1&#xff09;的格式&#xff0c;当我改了小版本的号的时候&#xff08;10…

redisserver一闪而过 redis闪退解决版本

1.进入Redis根目录 2.输入redis-server 或 redis-server.exe redis.windows.conf 启动redis命令&#xff0c;看是否成功。 执 一闪而过的问题 可能是因为已启动或者其他问题&#xff0c;需要重启 先输入redis-cli.exe再输入shutdown再输入redis-server.exe redis.windows.c…

<Linux> 文件理解与操作

目录 前言&#xff1a; 一、关于文件的预备知识 二、C语言文件操作 1. fope 2. fclose 3. 文件写入 3.1 fprintf 3.2 snprintf 三、系统文件操作 1. open 2. close 3. write 4. read 四、C文件接口与系统文件IO的关系 五、文件描述符 1. 理解文件描述符 2. 文…

水面倒影可视化渲染方法

水面材质在三维可视化场景中的使用非常广泛。水面材质非常重要的一个光学特性就是反射倒影&#xff0c;有了倒影的加持能使水面更加逼真的渲染出来。本文主要讨论水面材质中倒影的渲染方法。 要有倒影&#xff0c;必须先有水面&#xff0c;第一步要做的就是确定水面所在的平面…

【Spring MVC】Filter 过滤器异常处理 HandlerExceptionResolver 分析

文章目录 前言版本说明测试 Demo1、自定义过滤器 DemoFilter2、自定义业务异常 ServiceException3、自定义异常处理类 DemoExceptionHandler4、DemoController5、请求测试 问题分析1、日志打印记录2、Debug 方法 解决方案1、修改自定义过滤器2、请求测试 解决方案分析1、日志打…

苹果cms搭建教程附带免费模板

准备工作: 一台服务器域名源码安装好NGINX+PHP7.0+MYSQL5.5 安装php7.0的扩展,fileinfo和 sg11,不安装网站会搭建失败。 两个扩展都全部安装好了之后 点击-服务-重载配置 这样我们的网站环境就配置完成啦 下载苹果cms 苹果cms程序github链接:选择mac10!下载即可 http…

YARN工作流程详解

图1 图2 图1 -作业提交阶段&#xff1a; 1、client 提交job,向 ResourceManager【RM】 申请job_id; 2、RM 返回 job_id 及资源提交路径 给 client 3、client 把job所需的资源提交 到 3中指定的路径中 4、client 上传完成资源后&#xff0c;向RM 发送执行作业请求&#xff0c;RM…

Linux常见指令(1)

一、使用XShell登陆主机 我们在XShell中输入以下指令&#xff0c;再输入密码就可以远程连接到我们的主机。 ssh root公网ip 另外我们注意一下XShell下的复制粘贴&#xff0c;我们的CV大法已经没有用啦&#xff1a; 复制&#xff1a; Ctrl Insert 粘贴&#xff1a; Shift Ins…

MySQL基本SQL语句(下)

MySQL基本SQL语句&#xff08;下&#xff09; 一、扩展常见的数据类型 1、回顾数据表的创建语法 基本语法&#xff1a; mysql> create table 数据表名称(字段名称1 字段类型 字段约束,字段名称2 字段类型 字段约束,...primary key(主键字段 > 不能为空、必须唯一) ) …

[原创](免改BIOS)使用Clover升级旧电脑-(骨灰级)修改Clover的config.plist文件

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XXQQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi…

Grabcut算法在图片分割中的应用

GrabCut算法原理 Grabcut是基于图割(graph cut)实现的图像分割算法&#xff0c;它需要用户输入一个bounding box作为分割目标位置&#xff0c;实现对目标与背景的分离/分割&#xff0c;与KMeans与MeanShift等图像分割方法不同。 Grabcut分割速度快&#xff0c;效果好&#xff0…

关于微服务的思考

目录 什么是微服务 定义 特点 利弊 引入时机 需要哪些治理环节 从单体架构到微服务架构的演进 单体架构 集群和垂直化 SOA 微服务架构 如何实现微服务架构 服务拆分 主流微服务解决方案 基础设施 下一代微服务架构Service Mesh 什么是Service Mesh&#xff1f…

ElasticSearch学习笔记(狂神说)

ElasticSearch学习笔记&#xff08;狂神说&#xff09; 视频地址&#xff1a;https://www.bilibili.com/video/BV17a4y1x7zq 在学习ElasticSearch之前&#xff0c;先简单了解一下Lucene&#xff1a; Doug Cutting开发是apache软件基金会 jakarta项目组的一个子项目是一个开放…

4面试题--数据库(补充)

隔离性问题 若不考虑隔离性则会出现以下问题 1. 脏读&#xff1a;指⼀个事务在处理数据的过程中&#xff0c;读取到另⼀个 未提交 事务的数据 2. 不可重复读&#xff1a;指对于数据库中的某个数据&#xff08;同⼀个数据项&#xff09;&#xff0c;⼀个事务内的多次查询却…

ICPC合肥退役小记

退役了。 现在我坐在合肥回济南的高铁上&#xff0c;外面天都黑了&#xff0c;刚刚刷小红书刷到一句话&#xff0c;“后来啊&#xff0c;一个清晨&#xff0c;大雾散尽&#xff0c;不止清晨&#xff0c;不止大雾”。 遗憾必然是有的。从大一开始每天熬夜刷题打cf…

电子学会C/C++编程等级考试2021年09月(三级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:余数相同问题 已知三个正整数 a,b,c。 现有一个大于1的整数x,将其作为除数分别除a,b,c,得到的余数相同。 请问满足上述条件的x的最小值是多少? 数据保证x有解。输入: 一行,三个不大于1000000的正整数a,b,c,两个整数…