你的代碼工作或多或少三立對我來說,除非我表示EOF(控制-d我的機器前輸入輸入不跟任何空白(空格,製表符,換行符)的一個字;如果您使用Control-Z,則表示您在Windows上運行)。如果您沒有最終的空格指示EOF,則最後一個單詞不會添加到直方圖中。當然,您還應該檢查單詞長度是否不太大,以免在wordlength
數組之外索引(if (nc > MAXSIZE) nc = MAXSIZE;
將所有超長單詞計爲相同大小)。
經過主處理循環之後,您應該檢查是否nc > 0
,如果是,請在wordlength
中增加相應的條目。
也考慮從<ctype.h>
使用isspace()
。
我儘可能使用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-like系統)。修訂版稍微好一些;它會計算輸入的最後一個單詞,即使它沒有跟隨空格或換行符。
如果根據推斷您正在使用Windows,那麼終端I/O模型可能會有所不同。特別是,C標準要求文本文件(可能包括終端輸入)必須在EOF之前以換行符結束;最後一個換行符之後的任何字符都可能被丟棄,但這取決於平臺。二進制文件的行爲是不同的。如果上一次換行符後面的數據與您報告的行爲一致。這可能是預期的行爲 - 如果您查看未識別系統的文檔。這是P J Plauger在其優秀(但有些過時的)「標準C庫」中確定的實現之間的區別之一。但是,如果我的假設是正確的,那麼我仍然希望清楚地說明你的代碼是正確的(足夠)。麻煩在於你的期望不符合系統記錄的行爲。請注意,報告您工作的平臺有時非常重要。當你侵犯邊緣情況時,它往往更爲重要。而且你仍然很難碰到getchar()
中的一個bug。順便說一句,當我測試時,我需要鍵入Control-D兩次(這就是我期望必須做的)。第一次將我輸入的字符(abc
)刷新爲3字節讀取的程序;第二個也將我輸入的字符(全部爲0)刷新爲程序的0字節讀數,然後將其解釋爲EOF getchar()
。我還測試了abc
(最後一個空白),然後是EOF。你的代碼沒有空白,沒有統計abc
;它確實包括了abc
,後面跟着一個空格。
請按照C99(舊C標準;當前標準爲C2011)的要求學習編寫C語言,併爲main()函數提供顯式返回類型。當你處理命令行參數時,當你忽略參數列表和'int main(int argc,char ** argv)'時強烈推薦'int main(void)'。 – 2012-02-07 14:49:42
對你而言,不幸的是,stdin通常是行緩衝的,你必須按下回車鍵來輸入你輸入的任何鍵盤輸入。就是這樣。但是,你可以使它無緩衝或使其不能做到這一點。 – 2012-02-07 14:50:19
@Jonathan感謝您的建議。我正在閱讀一本書,並試圖編寫解決方案,這些解決方案只使用直到閱讀的信息。 – bubble 2012-02-07 14:56:22