#include <stdio.h>
#define MAX_LEN 10 //單詞的最大長度
#define IN 1
#define OUT 0
int main(void)
{
int len; //每個單詞的長度
int wc[MAX_LEN+1] = {0}; //每個長度對應的單詞數
int c, i, j;
int state;
int maxnum=0; //wc[]中的最大數
len = c = i = 0;
state = OUT;
while((c = getchar()) != EOF) {
if(c == ' ' || c == '\t' || c == '\n') {
if(state == IN) { //或者 if(len > 0)
if(len >= MAX_LEN) {
wc[MAX_LEN]++;
len = MAX_LEN; //單詞長度大於MAX_LEN
}
else {
wc[len]++;
}
if(maxnum < wc[len])
maxnum = wc[len];
len = 0;
state = OUT;
}
}
else if(state == OUT) {
state = IN;
len = 0; //單詞真實的長度爲len+1
}
else
len++;
}
putchar('\n');
for(i = maxnum; i > 0; i--) {
printf("%3d|", i);
for(j = 0; j <= MAX_LEN; j++) {
if(wc[j] >= i)
printf(" * ");
else
printf(" ");
}
putchar('\n');
}
printf(" +");
for(i = 0; i <= MAX_LEN; i++)
printf("___");
printf("\n ");
for(i = 0; i < MAX_LEN; i++) {
printf("%3d", i+1);
}
printf(" >10");
putchar('\n');
return 0;
}
效果圖
EOF釋疑(轉自這裏)
首先要明白一點,EOF並不是標誌結尾的特殊字符,而是文字流(stream,標準輸入或者文件)達到結尾時返回的一個信號量,在stdio.h中定義爲常量,其值常常爲-1,只在文本文件中存在,二進制文件中不存在。
1.如果是從標準輸入中讀取stream,如下程序
int c;//定義爲int類型,因爲返回值EOF(-1)是int類型的
while((c=getchar()) != EOF)
putchar(c);
由於標準輸入中無法事先判斷長度,無法判斷是否是End Of File,所以需要手動輸入一個字符表示達到EOF。
Windows中,在新的一行開頭中按下Ctrl+Z,表示達到EOF(因爲Windows輸入是阻塞式的,所以在敲下換行鍵之前不會檢測Ctrl+Z);
Linux中,在新的一行開頭,按下Ctrl-D,表示達到EOF(或者在一行的中間按兩次Ctrl-D,因爲在一行的中間按下Ctrl-D,表示輸出"標準輸入"的緩存區);
2.如果是從文件中讀取stream,一般寫成如下形式
int c;
while ((c = fgetc(fp)) != EOF){
c = fgetc(fp);
do something;
}
這樣寫有一個問題。fgetc()不僅是遇到文件結尾時返回EOF,而且當發生錯誤時,也會返回EOF。因此,C語言又提供了feof()函數,用來保證確實是到了文件結尾。上面的代碼feof()版本的寫法就是:int c;
while (!feof(fp)) {
c = fgetc(fp);
do something;
}
但是,這樣寫也有問題。fgetc()讀取文件的最後一個字符以後,C語言的feof()函數依然返回0,表明沒有到達文件結尾;只有當fgetc()向後再讀取一個字符(即越過最後一個字符),feof()纔會返回一個非零值,表示到達文件結尾。所以,按照上面這樣寫法,如果一個文件含有n個字符,那麼while循環的內部操作會運行n+1次。所以,最保險的寫法是像下面這樣:
int c = fgetc(fp);
while (c != EOF) {
do something;
c = fgetc(fp);
}
if (feof(fp)) {
printf("\n End of file reached.");
} else {
printf("\n Something went wrong.");
}
這樣在讀取stream時,如果c = fgetc(fp) 讀到的是二進制的-1,怎麼區分讀到的c(-1)跟信號值(-1)呢?
一種解釋(不一定對,歡迎討論):
在文本文件中,數據以字符的ASCII碼值的形式存放。ASCII碼值的範圍是0~255,不可能出現-1,-1實際上是‘-’ 和‘1’,而fgetc是文本視圖處理文件的,因此可以用EOF作爲文件結束標誌輸入的。
注意:EOF只存在文本視圖中,二進制視圖是通過比較文件長度來判斷是否達到文件結尾。