Trying to make program that counts number of bytes in a specified file (in C)

3.7k views Asked by At

I am currently attempting to write a program that will tell it's user how many times the specified 8-bit byte appears in the specified file.

I have some ground work laid out, but when it comes to making sure that the file makes it in to an array or buffer or whatever format I should put the file data into to check for the bytes, I feel I'm probably very far off from using the correct methods.

After that, I need to check whatever the file data gets put in to for the byte specified, but I am also unsure how to do this. I think I may be over-complicating this quite a bit, so explaining anything that needs to be changed or that can just be scrapped completely is greatly appreciated.

Hopefully didn't leave out any important details.

Everything seems to be running (this code compiles), but when I try to printf the final statement at the bottom, it does not spit out the statement. I have a feeling I just did not set up the final for loop correctly at all..

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
//#define BUFFER_SIZE (4096)
main(int argc, char *argv[]){       //argc = arg count, argv = array of arguements

    char buffer[4096];
    int readBuffer;
    int b;
    int byteCount = 0;
    b = atoi(argv[2]);
    FILE *f = fopen(argv[1], "rb");

    unsigned long count = 0;
    int ch;

    if(argc!=3){                 /* required number of args = 3 */

        fprintf(stderr,"Too few/many arguements given.\n");
        fprintf(stderr, "Proper usage: ./bcount path byte\n");
        exit(0);
    }

    else{                       /*open and read file*/
        if(f == 0){
            fprintf(stderr, "File could not be opened.\n");
            exit(0);
        }



    }

    if((b <= -1) || (b >= 256)){            /*checks to see if the byte provided is between 0 & 255*/
        fprintf(stderr, "Byte provided must be between 0 and 255.\n");
        exit(0);
    }
    else{
        printf("Byte provided fits in range.\n");
    }

    int i = 0; 
    int k;
    int newFile[i];

    fseek(f, 0, SEEK_END);
    int lengthOfFile = ftell(f);


    for(k = 0; k < sizeof(buffer); k++){
        while(fgets(buffer, lengthOfFile, f) != NULL){
            newFile[i] = buffer[k];
            i++;
        }
    }

    if(newFile[i] = buffer[k]){
        printf("same size\n");
    }



    for(i = 0; i < sizeof(newFile); i++){
        if(b == newFile[i]){
            byteCount++;
        }
        printf("Final for loop is working???"\n");
    }


}
2

There are 2 answers

3
chux - Reinstate Monica On BEST ANSWER

OP is mixing fgets() with binary reads of a file.

fgets() reads a file up to the buffer size provided or reaching a \n byte. It is intended for text processing. The typical way to determine how much data was read via fgets() is to look for a final \n - which may or may not be there. The data read could have embedded NUL bytes in it so it becomes problematic to know when to stop scanning the buffer. on a NUL byte or a \n.

Fortunately this can all be dispensed with, including the file seek and buffers.

// "rb" should be used when looking at a file in binary. C11 7.21.5.3 3
FILE *f = fopen(argv[1], "rb");  
b = atoi(argv[2]);
unsigned long byteCount = 0;
int ch;
while ((ch = fgetc(f)) != EOF) {
  if (ch == b) {
    byteCount++;
  }
}

The OP error checking is good. But the for(k = 0; k < sizeof(buffer); k++){ loop and its contents had various issues. OP had if(b = newFile[i]){ which should have been if(b == newFile[i]){

0
jim mcnamara On

Not really an ANSWER -- Chux corrected the code, this is just more than fits in a comment.

#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
   struct stat st;
   int rc=0;
   if(argv[1])
   {
      rc=stat(argv[1], &st);
      if(rc==0)
        printf("bytes in file %s: %ld\n", argv[1], st.st_size);
      else
      {
        perror("Cannot stat file");
        exit(EXIT_FAILURE);
      }
      return EXIT_SUCCESS;
   }
   return EXIT_FAILURE;
}

The stat() call is handy for getting file size and for determining file existence at the same time. Applications use stat instead of reading the whole file, which is great for gigantic files.