以下代码显示奇怪的行为。如果我按下换行符给出输入,那么只打印直方图值,否则如果我直接输入EOF(^ Z),它会显示全零。 getchar()函数是否存在问题,即仅在按下换行符时才接受输入。
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
#define MAXLEN 50
/* count lines, words, and characters in input */
main()
{
int c, i, j, nc, state;
int wordlength[MAXLEN];
state = OUT;
nc = 0;
for (i = 0; i < MAXLEN; i++)
wordlength[i] = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t') {
if (state == IN) {
wordlength[nc-1]++;
}
state = OUT;
}
else if (state == OUT) {
//putchar('\n');
state = IN;
nc = 0;
}
if (state == IN) {
++nc;
}
}
for (j = 0; j < MAXLEN; j++)
printf("\n%d - %d",j,wordlength[j]);
for (i = 10; i >= 0; i--) {
for (j = 0; j < MAXLEN; j++)
printf(((wordlength[j] > i)?"|":" "));
printf("\n");
}
}
答案 0 :(得分:1)
你的代码或多或少对我有用,除非我在我的机器上指示EOF( Control-D )之前输入一个输入单词后面没有任何空格(空格,制表符,换行符) ;如果您使用 Control-Z ,则表明您在Windows上运行。如果指示EOF而没有最终空白区域,则最后一个单词不会添加到直方图中。当然,您还应检查单词长度是否太大,以便不在wordlength
数组(if (nc > MAXSIZE) nc = MAXSIZE;
之外进行索引,以将所有非常长的单词计为相同大小)。 / p>
在主处理循环之后,您应该检查是否nc > 0
,如果是,请在wordlength
中增加相应的条目。
也可以考虑使用isspace()
中的<ctype.h>
。
我尽可能使用enum
而不是#define
,以便调试器中的符号可用。你小心避免了一个常见的错误;您将变量c
变为int
,而不是char
。
#include <stdio.h>
enum { IN = 1, OUT = 0 }; /* inside, outside a word */
enum { MAXLEN = 50 };
/* count lines, words, and characters in input */
int main(void)
{
int c, i, j, nc, state;
int wordlength[MAXLEN];
state = OUT;
nc = 0;
for (i = 0; i < MAXLEN; i++)
wordlength[i] = 0;
while ((c = getchar()) != EOF)
{
if (c == ' ' || c == '\n' || c == '\t')
{
if (state == IN)
{
if (nc > MAXLEN)
nc = MAXLEN; /* All long words grouped together */
wordlength[nc-1]++;
}
state = OUT;
}
else if (state == OUT)
{
state = IN;
nc = 0;
}
if (state == IN)
++nc;
}
if (nc > 0)
{
if (nc > MAXLEN)
nc = MAXLEN; /* All long words grouped together */
wordlength[nc-1]++;
}
for (j = 0; j < MAXLEN; j++)
printf("\n%d - %d", j, wordlength[j]);
for (i = 10; i >= 0; i--)
{
for (j = 0; j < MAXLEN; j++)
putchar( (wordlength[j] > i) ? '|' : ' ');
printf("\n");
}
return 0;
}
你说你的机器出了问题。我会非常谨慎地声称在系统中发现了一个错误,尤其是在getchar()
这样一个明显的调用中。我不能排除这种可能性,但这将是我想到的最后一件事。在考虑getchar()
中存在错误之前,我会花很多时间来解决我做错的事情。
在评论中,您要求告诉您为什么您的程序无法在您的环境中运行。由于您尚未正式确定运行程序的平台/环境,因此无法实现。
但是,我已经证明了你原来的as-posted程序在类似Unix的环境中运行得相当合理(我正在MacOS X 10.7.2上进行测试,但对于任何其他类似的类Unix系统它都会起作用。 )。修订版略好一些;它将计算输入的最后一个单词,即使它后面没有空格或换行符。
如果推断,您正在使用Windows,那么终端I / O模型可能会有所不同。特别是,C标准要求文本文件(可能包括终端输入)必须在EOF之前以换行符结尾;可以丢弃最后一个换行符之后的任何字符,但这取决于平台。二进制文件的行为是不同的。如果是最后一个换行符后的数据,则与您报告的行为一致。它可能是预期的行为 - 如果您查看未识别系统的文档。这是P J Plauger在他的优秀(但有点过时)的“标准C库”中确定的实现之间的差异之一。
然而,如果我假设的是正确的,那么我仍然希望明确你的代码是正确的(足够);问题在于您的期望与系统记录的行为不符。请注意,报告您正在使用的平台有时至关重要。当你正在侵占边缘案件时,它往往更为重要。你在getchar()
中遇到一个错误的可能性极小。
顺便说一下,当我测试时,我需要两次输入 Control-D (这就是我期望的那样)。第一次将我在行(abc
)上输入的字符刷新为程序,作为3字节读取;第二个也将我输入的字符(全部为零)刷新为程序,作为0字节读取,然后由getchar()
解释为EOF。我还测试了abc
(最后一个空白),然后是EOF。您的代码没有计算abc
没有空白;当它跟着一个空白时,它确实计算了abc
。