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

致敬经典 << KR C >> 之打印输入单词水平直方图和以每行一个单词打印输入 (练习1-12和练习1-13)

1. 前言

不知道有多少同学正在自学C/C++, 无论你是一个在校学生, 还是已经是上班族. 如果你想从事或即将从事软件开发这个行业, C/C++都是一个几乎必须要接触的系统级程序开发语言. 虽然现在有Rust更安全的系统级编程语言作为C/C++的替代, 但作为入门, C应该还是要好好学的. C最早由B语言改进而来. 不出意外你应该已经想到了C/UNIX都是贝尔实验室的里奇和汤普逊所开发. 一个C影响了后来一系列开发语言, 一个UNIX影响了后来一系列操作系统. K&R C就是经典C, 那时C还没有标准化, 还没有ANSI标准, 所以K&R就是早期的C标准.

确切的说 K&R C 指的是由 C 语言创始人 Dennis Ritchie 和 Brian Kernighan 在其经典著作《The C Programming Language》(1978年第一版)中描述的早期 C 语言标准。也被称为 "经典 C" 或 "传统 C". Brian Kernighan 就是 K&R C中的K, Hello World程序就是他首先使用的. 当然这本书有第2版, 引入了一些ANSI的C标准. 这本书的练习题除部分少量的过时外, 大部分编程题还是很值得自己实践练习的.我这有两道练习题, 自己写了一下, 虽然不难, 但如果是初学者, 还是可以自己写完, 再看看别人的, 多参考学习.

写这些编程题有个感觉, 就像造车, 发动机要自己造, 变速箱要自己造, 底盘也要自己造, 外观要自己设计, 一切细节都要详细了解, 没有封装, 除了少量标准库函数可用, 一切要自己动手写. 就算是标准库中的函数, 你也完全根据它的功能, 自己去实现, 自己来封装. 那些大师早期哪有现成的库, 都是他们自己写的. 所以要多动手去写, 去实现自己的版本.

第 1 章内容不多, 尽量用本章介绍的内容来完成作业.

2. 练习 1 - 12 习题及代码

下面是两个练习题:

练习1-12  编写一个程序, 以每行一个单词的形式打印其输入.

下面是代码, 因为很短, 所以没有加注释, 另外输入中如果有多个空白符 (制表, 空格), 会忽略:

#include <stdio.h>int main(void)
{int ch;while ((ch = getchar()) != EOF) {if (ch != ' ' && ch != '\t' && ch != '\n') {putchar(ch);} else {if (ch == '\n') { putchar(ch);} else {while ((ch = getchar()) == ' ' || ch == '\t') {continue;}putchar('\n');putchar(ch);}}}return 0;

运行结果:

3. 练习 1 - 13 习题及代码

下面这道题在我的另几篇文章已实现垂直方向的直方图, 有兴趣的同学可以看另几篇文章.

练习1-13  编写一个程序, 打印输入中单词的直方图. 水平方向的直方图比较容易绘制, 垂直方向的直方图则要困难些.

下面是代码 (代码有一些问题,有兴趣的同学可以改进):

#include <stdio.h>
#define MAX 20      /*统计最长为20个字符的单词*/
#define MAXNUM 26   /*某个长度最多统计25个*/void initwords(int *pw, int len);
void countwords(int *pw, int len);
void printhtgm(int *pw, int len);
void putpatterns(char ch, int n, int width);
void putspaces(int n);
void putline(int n);
void printXnum(int n);
int main(void)
{int words[MAX + 1];          /*统计最长20个字符的单词*/initwords(words, MAX + 1);   /*初始化单词数量数组*/countwords(words, MAX + 1);  /*统计输入各长度㼿司数量*/printhtgm(words, MAX + 1);   /*打印水平直方图*/return 0;
}/*初始化单词数量数组*/
void initwords(int *pw, int len)
{int i;for (i = 1; i < len; i++) { pw[i] = 0; }
}/*统计各长度单词数量*/
void countwords(int *pw, int len)
{int ch, wordlen, wordin;wordlen = wordin = 0;while ((ch = getchar()) != '#') {if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {if (wordin == 0) { wordin = 1;}if (wordlen < len - 1) { wordlen++; }} else if (ch == ' ' || ch == '\t' || ch == '\n') {if (wordin == 1) {wordin = 0;if (pw[wordlen] < MAXNUM - 1) { pw[wordlen]++; }wordlen = 0;}}}if (pw[wordlen] < MAXNUM - 1) { pw[wordlen]++; }
}/*打印水平直方图*/
void printhtgm(int *pw, int len)
{int i;putline(2);putspaces(5);putchar('Y');putline(1);for (i = len - 1; i > 0; i--) {putspaces(3);printf("%2d", i);putchar('|');putpatterns('*', pw[i], 2);putline(1);}putspaces(5);putchar('+');putpatterns('-', MAXNUM * 2, 1);putchar('>');putspaces(1);putchar('X');    putline(1);printXnum(20);putline(2);   
}/*打印X轴数字*/
void printXnum(int n)
{if (n < 1 || n > MAXNUM) { return; }int i;putspaces(6);for (i = 1; i <= n; i++) { if (i >= 10) { putchar(' '); }printf("%2d", i); }
}/*打印直方图案*/
void putpatterns(char ch, int n, int width)
{if (n < 1 || n > MAXNUM * 2) { return; }int i;for (i = 0; i < n; i++) {putspaces(width - 1); putchar(ch); }
}/*打印Y轴缩进*/
void putspaces(int n)
{int i;for (i = 0; i < n; i++) {putchar(' ');}
}/*空格打印*/
void putline(int n)
{int i;for (i = 0; i < n; i++) { putchar('\n'); }
}

运行结果:

下面是输入一些测试单词

下面是输入歌曲 << The day you went away  >> 的歌词结果:

4. 结语

喜欢就点赞收藏, 您的支持是我创作的动力.

http://www.xdnf.cn/news/6816.html

相关文章:

  • 最小二乘法拟合直线,用线性回归法、梯度下降法实现
  • SLAM定位常用地图对比示例
  • 【深度学习新浪潮】大模型时代,我们还需要学习传统机器学习么?
  • 计算机视觉与深度学习 | Python实现EMD-VMD-LSTM时间序列预测(完整源码和数据)
  • React Flow 节点事件处理实战:鼠标 / 键盘事件全解析(含节点交互代码示例)
  • 跨国应用程序的数据存储方案常见的解决方案
  • R语言空间数据处理入门教程
  • Redis——过期删除策略和内存
  • golang读、写、复制、创建目录、删除、重命名,文件方法总结
  • AI517 AI本地部署 docker微调(失败)
  • Baklib知识中台构建企业智能服务新引擎
  • 板凳-------Mysql cookbook学习 (二)
  • 【新能源轻卡行驶阻力模型参数计算实战:从国标试验到续航优化】
  • Linux | mdadm 创建软 RAID
  • C# WPF .NET Core和.NET5之后引用System.Windows.Forms的解决方案
  • 服务间的“握手”:OpenFeign声明式调用与客户端负载均衡
  • uniapp +vue +springboot多商家订餐系统
  • BGP团体属性
  • NX二次开发——设置对象的密度(UF_MODL_set_body_density)
  • ESP32 PWM开发对比:底层驱动 VS Arduino封装,谁更适合你?
  • FEKO许可证与版本兼容性问题
  • 问答数字人解决方案​
  • 2025 年TTS 语音模型推荐:全面解析与对比
  • 力扣-78.子集
  • 常见激活函数——作用、意义、特点及实现
  • 生产级JVM参数优化
  • UL 1973:2022标准深度解析
  • eBPF及相关工具和技术介绍
  • p40上编译vllm0.8.6
  • Seata源码—4.全局事务拦截与开启事务处理二