подсчет слов в файле, например команда linux wc в C

Я пытаюсь написать что-то, что работает как команда Linux wc для подсчета слов, новых строк и байтов в любых файлах, и я могу использовать только чтение функции C. Я написал этот код, и я получаю правильные значения для новых строк и байтов, но я не получаю правильное значение для подсчитанных слов.

int bytes = 0;
int words = 0;
int newLine = 0;
char buffer[1];
int file = open(myfile,O_RDONLY);
if(file == -1){
  printf("can not find :%s\n",myfile);
}
else{
  char last = 'c'; 
  while(read(file,buffer,1)==1){
    bytes++;
    if(buffer[0]==' ' && last!=' ' && last!='\n'){
      words++;
    }
    else if(buffer[0]=='\n'){
      newLine++;
      if(last!=' ' && last!='\n'){
        words++;
      }
    }
    last = buffer[0];
  }        
  printf("%d %d %d %s\n",newLine,words,bytes,myfile);        
} 

person Youssef Khloufi    schedule 23.10.2012    source источник
comment
Каков ваш результат по сравнению с ожидаемым результатом?   -  person Jordan Kaye    schedule 24.10.2012
comment
Вам нужно логическое значение «inword», которое будет да, когда вы читаете слово, и нет, когда нет; когда он меняется на «в слове», вы увеличиваете количество слов. Определите слово, чтобы удовлетворить себя.   -  person Jonathan Leffler    schedule 24.10.2012
comment
вы знаете о регулярных выражениях? если да, то найдите libpcre и используйте его в своей программе, чтобы он был расширяемым ... в противном случае стоит потратить время, чтобы узнать о них   -  person Memos Electron    schedule 24.10.2012
comment
вот как считать слова в строке. Вы можете адаптировать его для вашего случая   -  person jfs    schedule 24.10.2012


Ответы (2)


Вы должны изменить свою логику. Вместо того, чтобы искать пробел и увеличивать количество слов, ищите не пробел, чтобы увеличить количество слов. Кроме того, может помочь использование переменной состояния вместо просмотра последнего символа:

int main(void)
{
   const char *myfile = "test.txt";
   int bytes = 0;
   int words = 0;
   int newLine = 0;
   char buffer[1];
   int file = open(myfile,O_RDONLY);
   enum states { WHITESPACE, WORD };
   int state = WHITESPACE;
   if(file == -1){
      printf("can not find :%s\n",myfile);
   }
   else{
      char last = ' '; 
      while (read(file,buffer,1) ==1 )
      {
         bytes++;
         if ( buffer[0]== ' ' || buffer[0] == '\t'  )
         {
            state = WHITESPACE;
         }
         else if (buffer[0]=='\n')
         {
            newLine++;
            state = WHITESPACE;
         }
         else 
         {
            if ( state == WHITESPACE )
            {
               words++;
            }
            state = WORD;
         }
         last = buffer[0];
      }        
      printf("%d %d %d %s\n",newLine,words,bytes,myfile);        
   } 

}

Похоже, что у wc есть некоторая логика в отношении знаков пунктуации, не являющихся словами, которую этот код не обрабатывает.

person Scooter    schedule 23.10.2012

используйте функцию isspace(char ch) для проверки пробелов.

int isInWord = 0;/*false*/
while(read(file,buffer,1)==1){
    bytes++ ;
    if(!isspace(buffer[0])){
         isInWord = 1;/*true*/
         continue;
    }else{
      if(buffer[0] == '\n'){
        newLine++;
      }else{
        if(isInWord)
         words++;
      }
      isInWord = 0;
   }
}
person Aniket Inge    schedule 23.10.2012
comment
он терпит неудачу, если файл заканчивается не пробелом, например, "word". Сравните с этим алгоритмом - person jfs; 24.10.2012
comment
Ах, я вижу ошибку. Спасибо @J.F.Sebastian - person Aniket Inge; 24.10.2012