Hello, I'm a newbie,
this is an a simple util that gives the percentage of the word length of
the input files and a simple histogramm. (It's an exersise of my ANSI C
manual) The problem is that using it without input files and options
frummel~$ buggy
it takes input from stdin (ok) but giving EOF (^D) causes a segmentation
fault . Using it without input files but with an option f.e.
frummel~$ buggy -H
all runs OK. I took care that argv[v] never goes negative : v is
unsigned. What's wrong ;
Any other notations, suggestions etc are wellcome.
Thank you
Antonis
#include <stdio.h>
#include <unistd.h>
#define MAX 1000
#define IN 0
#define OUT 1
#define YES 1
#define NO 0
int wordlen(FILE *file);
void result(int count[],int max);
void histo(int count[],int max);
float percent(double all, int part);
double allwds ;
int eof ;
main(int argc, char *argv[])
{
int c ,i,state,len,opt,filecount ;
short flagnum , flaghisto, options ;
int count[MAX];
FILE *file ;
int eof ; /*because ungetc() cannot return EOF to buffer */
char *fname ;
int unsigned v ;
state=OUT ;
flagnum=flaghisto=options=NO ;
allwds=0 ;
file=stdin ;
eof=0 ;
filecount=0 ;
fname="foo" ;
/*############## Let's parse options */
while((opt = getopt(argc, argv, "hHn")) != EOF) {
switch(opt) {
case 'h':
fprintf(stderr,"\n\n %s options :\n-n numeric (default)\n-H histogram\n-h
prints this file\n\n",argv[0]);
return ;
case 'H':
flaghisto=YES ;
options=YES;
break ;
case 'n':
flagnum=YES;
options=YES;
break ;
case '?':
fprintf(stderr,"\a");
return;
}
}
/*############ collect input files*/
for (v=argc-1; ( ((argv[v][0])!='-') && (v>0) ) ; v--) { /*CLOSES BEFORE MAIN*/
if( ( file=fopen(argv[v],"r") )==NULL){
fprintf(stderr,"\n\n\a %s: can't open %s\n\n",argv[0],argv[v]);
++filecount ;
continue ;
}
fname=argv[v];
nofiles:
++filecount ;
/*########### central controls */
allwds=0 ;
for (i=0 ; i<MAX ; ++i){
count[i]=0 ; /* <- Ligh fasina ston count[] */
}
while (eof!=EOF &&(c=getc(file))!=EOF){
if (isspace(c))
state=OUT ;
else{
state=IN ;
++allwds ;
}
if (state==IN){
len = wordlen(file);
++count[len];
}
}
eof=0 ;
/* ###### Let's format the output */
printf("\n %d ***** %s *****\n\n",filecount,fname);
if (options==NO)
flagnum=YES ; /*### numeric output is default */
if (flagnum==YES)
result(count, MAX);
if (flaghisto==YES)
histo(count,MAX);
if (file!=stdin)
fclose(file);
}
if(filecount==0) {
goto nofiles ;
file=stdin ;
}
}
/*=====================================================*/
int wordlen(FILE *file)
{
int c,i ;
int eof ;
i=1 ;
while ((c=getc(file))!=EOF && !isspace(c)){
++i ;
}
if (isspace(c)||c==EOF){
ungetc(c,file);
}
if (c==EOF) {
eof=EOF;
}
return i ;
}
/*=================================*/
void histo(int pinax[],int length)
{
float f;
int i , j ;
printf("\n");
for (i=0 ; i<length ;++i)
if (pinax[i]==0)
;
else{
f=percent(allwds,pinax[i]);
printf("%3d let: %5.2f%% |",i,f);
for (j=1 ; j<=f*2; ++j)
printf("*");
printf("\n");
}
}
/*==============================*/
void result(int pinax[],int length)
{
int i ;
printf("\n");
for (i=0 ; i<length ; ++i)
if (pinax[i]==0)
;
else{
printf("Words with ");
printf("%3d letters:\t",i);
printf("%6d\t%5.2f%%\n",pinax[i],percent(allwds,pinax[i]));
}
printf("Sum: %g words.\n",allwds);
}
/*========================*/
float percent(double all, int part)
{
float f ;
f=100 * (part/all);
return f ;
}