0

I have the following code that simulate the wc command from linux. I need to use a buffer with the dimension of 4096 but for some reason when I execute this code i get the following result:

0 0 0 wcfile

I get 0 lines, words and bytes even if the file is not empty. The code that I am using is the following:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define LUNG_BUF 4096

int main(int argc, char** argv)
{
int bytes = 0;
int words = 0;
int newLine = 0;

char buffer[LUNG_BUF];
enum states { WHITESPACE, WORD };
int state = WHITESPACE; 
 if ( argc !=2 )
 {
     printf( "Nu ati introdu snumele  fisierului\n%s", argv[0]);
 }
 else{
     FILE *file = fopen( argv[1], "r");

   if(file == 0){
      printf("can not find :%s\n",argv[1]);
   }
   else{
            char *thefile = argv[1];

       while (read(fileno(file),buffer,LUNG_BUF) ==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;
         }

      }        
      printf("%d %d %d %s\n",newLine,words,bytes,thefile);        
   }
 } 

}```
gameloverr
  • 53
  • 1
  • 8

1 Answers1

1

read attempts to read up to LUNG_BUF bytes into buffer and returns the number of bytes actually read (or zero in case of end-of-file or -1 to indicate an error).

That means the check for == 1 will fail most of the time.

If you want to interprete the data it makes also sense to read one byte less then the maximum buffer size to be able to place a terminating NUL byte at the end of the buffer.

You can then evaluate this data, for example, by using a pointer that is set to the beginning of the buffer at each loop pass.

So your code would look like this then:

size_t n;
while ((n = read(fileno(file), buffer, LUNG_BUF - 1)) > 0) {
    buffer[n] = '\0';
    char *ptr = buffer;
    while (*ptr) {
        bytes++;
        if (*ptr == ' ' || *ptr == '\t') {
            state = WHITESPACE;
        } else if (*ptr == '\n') {
            newLine++;
            state = WHITESPACE;
        } else {
            if (state == WHITESPACE) {
                words++;
            }
            state = WORD;
        }
        ptr++;
    }
}

Another option would be to use fgets that provide the data of one line or up to 4095 bytes (since at least one terminating NUL byte is appended by fgets) if the line is actually longer.

So your loop just slightly modified would look like this:

while (fgets(buffer, sizeof(buffer), file)) {
    char *ptr = buffer;
    while (*ptr) {
    ...
Stephan Schlecht
  • 26,556
  • 1
  • 33
  • 47