编写一个读入文件的字符数并打印直方图
- /*......*/
- #include<stdio.h>
- #include<malloc.h>
- #include<stdlib.h>
- #define LEN sizeof(struct wordcount)
- #define IN 1
- #define OUT 0
- int word_Allcharcount(int n,char filename[]);
- int word_MaxCharacter(char filename[]);
- char filename[20];
- struct wordcount
- {
- int wordlen;
- int wordnt;
- struct wordcount *next;
- }
- /*-----------------------------------------------*/
- /*********************主函数**********************/
- main()
- {
- struct wordcount *head;
- struct wordcount *Llist(void);
- void input(struct wordcount *head);
- scanf("%s",filename);
- head=Llist();
- input(head);
- }
- /*-----------------------------------------------*/
- /*********************charcount函数***************/
- /*读出指定字符数的单词出现几次*/
- int word_Allcharcount(int n,char filename[])
- {
- int word_CharacterCount;
- int word_Count;
- int state;
- int c;
- FILE *fp;
- word_Count=0;
- state=OUT;
- word_CharacterCount=0;
- if ((fp=fopen(filename,"r"))==NULL)
- {
- printf("cannot open flie/n");
- exit(0);
- }
- else
- do
- {
- c=fgetc(fp);
- if (c==' '||c=='/n'||c=='/t'||c==EOF)
- {
- state=OUT;
- if (word_CharacterCount==n)
- ++word_Count;
- word_CharacterCount=0;
- }
- else if (state=OUT)
- {
- state=IN;
- ++word_CharacterCount;
- }
- else if (c=='.')
- ;
- else if (c==',')
- ;
- else if (c=='!')
- ;
- else if (c=='?')
- ;
- else if (c==':')
- ;
- else if (c=='/'')
- ;
- else
- ++word_CharacterCount;
- }while (c!=EOF);
- return(word_Count);
- }
- /*-----------------------------------------------*/
- /******************max函数************************/
- /*字符数最长的单词*/
- int word_MaxCharacter(char filename[])
- {
- int word_CharacterCount;
- int word_CharacterRemember;
- int c;
- int state;
- FILE *fp;
- state=OUT;
- word_CharacterRemember=0;
- word_CharacterCount=0;
- if ((fp=fopen(filename,"r"))==NULL)
- {
- printf("cannot open flie/n");
- exit(0);
- }
- else
- while(!feof(fp))
- {
- c=fgetc(fp);
- if (word_CharacterCount>word_CharacterRemember)
- word_CharacterRemember=word_CharacterCount;
- if(c==' '||c=='/n'||c=='/t')
- {
- state=OUT;
- word_CharacterCount=0;
- }
- else if (state=OUT)
- {
- state=IN;
- ++word_CharacterCount;
- }
- else
- ++word_CharacterCount;
- }
- return(word_CharacterRemember);
- }
- /*-----------------------------------------------*/
- /******************Llist函数**********************/
- /*从1到max形成一个链表保存出现次数*/
- struct wordcount *Llist(void)
- {
- int word_Allcharcount(int n,char filename[]);
- int word_MaxCharacter(char filename[]);
- struct wordcount *head;
- struct wordcount *p1,*p2;
- int m,n;
- m=word_MaxCharacter(filename);
- p1=p2=(struct wordcount*)malloc(LEN);
- head=NULL;
- n=0;
- while(n<m)
- {
- ++n;
- p1->wordlen=n;
- p1->wordnt=word_Allcharcount(n,filename);
- if (n==1)
- head=p1;
- else if (n>1)
- p2->next=p1;
- p2=p1;
- p1=(struct wordcount*)malloc(LEN);
- }
- p2->next=NULL;
- free(p1);
- return(head);
- }
- /*-----------------------------------------------*/
- /*****************input函数***********************/
- /*输出函数*/
- void input(struct wordcount *head)
- {
- int m,n;
- int word_MaxCharacter(char filename[]);
- struct wordcount *p;
- m=word_MaxCharacter(filename);
- printf("this is chart/n");
- for(n=m;n>0;--n)
- {
- p=head;
- printf("%3d |",n);
- while(p->next!=NULL)
- {
- if ((n-(p->wordnt))<=0)
- printf("*");
- else
- printf(" ");
- p=p->next;
- }
- printf("/n");
- }
- printf(" ");
- printf("------------------");
- printf("/n");
- printf(" ");
- printf("0123456789");
- printf("/n");
- }
错误:
形参和实参类型不一样。
FILE定义要写在变量上面。
答案:
/* This program was the subject of a thread in comp.lang.c, because of the way it handled EOF.
* The complaint was that, in the event of a text file's last line not ending with a newline,
* this program would not count the last word. I objected somewhat to this complaint, on the
* grounds that "if it hasn't got a newline at the end of each line, it isn't a text file".
*
* These grounds turned out to be incorrect. Whether such a file is a text file turns out to
* be implementation-defined. I'd had a go at checking my facts, and had - as it turns out -
* checked the wrong facts! (sigh)
*
* It cost me an extra variable. It turned out that the least disturbing way to modify the
* program (I always look for the least disturbing way) was to replace the traditional
* while((c = getchar()) != EOF) with an EOF test actually inside the loop body. This meant
* adding an extra variable, but is undoubtedly worth the cost, because it means the program
* can now handle other people's text files as well as my own. As Ben Pfaff said at the
* time, "Be liberal in what you accept, strict in what you produce". Sound advice.
*
* The new version has, of course, been tested, and does now accept text files not ending in
* newlines.
*
* I have, of course, regenerated the sample output from this program. Actually, there's no
* "of course" about it - I nearly forgot.
*/
#include <stdio.h>
#define MAXWORDLEN 10
int main(void)
{
int c;
int inspace = 0;
long lengtharr[MAXWORDLEN + 1];
int wordlen = 0;
int firstletter = 1;
long thisval = 0;
long maxval = 0;
int thisidx = 0;
int done = 0;
for(thisidx = 0; thisidx <= MAXWORDLEN; thisidx++)
{
lengtharr[thisidx] = 0;
}
while(done == 0)
{
c = getchar();
if(c == ' ' || c == '/t' || c == '/n' || c == EOF)
{
if(inspace == 0)
{
firstletter = 0;
inspace = 1;
if(wordlen <= MAXWORDLEN)
{
if(wordlen > 0)
{
thisval = ++lengtharr[wordlen - 1];
if(thisval > maxval)
{
maxval = thisval;
}
}
}
else
{
thisval = ++lengtharr[MAXWORDLEN];
if(thisval > maxval)
{
maxval = thisval;
}
}
}
if(c == EOF)
{
done = 1;
}
}
else
{
if(inspace == 1 || firstletter == 1)
{
wordlen = 0;
firstletter = 0;
inspace = 0;
}
++wordlen;
}
}
for(thisval = maxval; thisval > 0; thisval--)
{
printf("%4d | ", thisval);
for(thisidx = 0; thisidx <= MAXWORDLEN; thisidx++)
{
if(lengtharr[thisidx] >= thisval)
{
printf("* ");
}
else
{
printf(" ");
}
}
printf("/n");
}
printf(" +");
for(thisidx = 0; thisidx <= MAXWORDLEN; thisidx++)
{
printf("---");
}
printf("/n ");
for(thisidx = 0; thisidx < MAXWORDLEN; thisidx++)
{
printf("%2d ", thisidx + 1);
}
printf(">%d/n", MAXWORDLEN);
return 0;
}