我正在学习《C编程语言》这本书中的C,我正在尝试解决练习1.13:
“写一个程序来打印输入的单词长度的直方图。画水平方向的直方图很容易;垂直方向的直方图更具挑战性。”
我写了代码,但是当我按CTRL+Z(文件结束)时,它显示的全是零,而不是单词的长度。
有没有人给予点提示,告诉我哪里做错了?
#include <stdio.h>
/* print a histogram of the length of words from input */
main()
{
int c, i, wordn, space;
int lengthn[20];
wordn = space = 0;
for (i = 0; i < 20; ++i)
lengthn[i] = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\t' || c == '\n')
if (space == 1) {
++wordn;
space = 0;
++i;
}
if (c != ' ' && c != '\t' && c != '\n') {
++lengthn[i];
space = 1;
}
}
printf("Length: ");
for (i = 0; i < 16; ++i)
printf("%d ", lengthn[i]);
printf("\n --------------------------------------------------------------\n");
printf("Word: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n");
}
字符串
4条答案
按热度按时间jhiyze9q1#
(因为OP是在寻求提示,而不是解决方案)
那么......在这个循环之后
i
等于什么呢?字符串
接下来你会在哪里使用它?
vom3gejh2#
字符串
在此循环之后,
i
的值将为i=20
因此必须在while循环之前初始化
i
cigdeys33#
我写了一个垂直方向的代码。我是新来的C,所以可能是代码不好。
字符串
b0zn9rqh4#
首先,下面是原始代码的输出,只更改了一行:
字符串
100
对于测试来说肯定有点太大了。型
而我们看到的第一个问题:
20
的字的负值有一些 * 一次性 * 错误。
下面是3个错误的一些提示和一个完整的替代示例,包括源代码、输出和参数。
问题:忽略长度为
MAXLEN
的单词我们不清楚
MAXLEN
是包含还是不包含,但在直方图中包含长度为MAXLEN
的单词似乎更自然,但无论如何,这些单词都应该被计算在内:在直方图中或在overflow
计数中:型
此处将其排除,因为
==
不匹配变更1
型
我们得到
型
现在我们有了这五个词的解释。
变更2
溢出中的巨大数字是由于此处的错误
型
因为在
printf
中,索引将一直到MAXHIST
,而wlen
从0
到MAXHIST-1
。有很多方法可以纠正这个问题。这里使用的是一个简单的方法:只需要向
wlen
数组中添加1个项。型
和使用
型
我们得到
型
更多关于代码的信息
所提供的代码基于1978年的一本书(K&R * 圣经 *)。从那时起,许多事情都发生了变化。例如,C-Faq经常被引用作为
C
编程的参考指南,其大部分可追溯到90年代。自2005年以来从未更新过...但是
C
和编程中的概念从那以后一直在变化。很多。第一次
型
for
中声明i
。例如,在C++
中,我们可以在switch
或while
或if
头文件中声明变量。重要的是要缩小任何变量的作用域-生存期-,特别是那些具有简单名称的变量,如i
和j
。我们可以写
型
我们也可以写
型
并删除这个
for
循环,因为程序只对数组运行一次。而不是
型
你应该使用
型
型
可以。但是第二个只用于打印
*
的循环是多余的。程序现在进行了这些更改
型
示例输出
型
关于状态机和另一个可能的问题
if
来控制状态,并且首先测试字母流,然后测试状态是很难遵循的。一般来说,有限状态机是循环中馈送的一些输入(在本例中是字母流)的过滤器,然后switch
得到state
并执行其操作。*overflow应该是这样一种状态:当一个单词达到溢出计数时,所有剩余的字母都被跳过。这是一种不同的行为,用这种方式编码会更容易。
*EOF也应该是一个状态:在
EOF
,我们只打印结果并终止。*但在EOF中,我们可能会扫描某个单词,而所提供代码的工作方式将被忽略。
另一个示例
我没有一步一步地修改提供的代码,而是在这里留下一个完整的
C
示例、示例输出和一些参数,以免有一个更大的帖子。示例中的一些结果
型
p
假定默认长度为4个字母,但用户可以在命令行上提供值,如p 12
中的值,最多可输入12个字母的单词。echo t te tes test tests | p 4
的行使用4作为最大长度,并且echo
和管道|
符号之间的文本作为输入来运行程序,因此它使测试更快更容易。示例的完整代码
型
关于示例代码
作为一个例子,下面是
S_IN
状态的代码,当我们在一个字内部时,一个新的c
值刚刚被读取:型
所有的州都使用类似的代码:在字母上有一个开关,这样写和管理状态就更快了。上面我们看到了其他3种状态的转换。
S_OVERFLOW
的代码类似于:型
这就是我想展示的。溢出的逻辑并没有隐藏在
S_IN
中,也没有跳过剩余字母的测试。FSM使抽象模型更容易。每个状态的代码可以由不同的人开发和测试。