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 ;
}

Reply via email to