Home > Back-end >  Counting the mose frequent char in a file
Counting the mose frequent char in a file

Time:11-28

For my CS class I need to write a program that reads an entire file. I've researched a whole bunch of different ways to do this with a string (the two for loops inside the while loops) and I've combined it with the way I was taught to read through a whole file. The problem is you can't index the frequency list with a char variable type (line). Is there an easier way to read through the file and do this?

# define MAX 200

void replace_most_freq(const char *filename, char c, FILE *destination) {
    // your code here
    FILE *in_file = NULL;
    in_file = fopen(filename, "r");
    if (!in_file) {
        fprintf(destination,
                "Error(replace_most_freq): Could not open file %s\n", filename);
        fclose(in_file);
        return;
    }
    int i, max = -1, len;
    int freq[256] = { 0 };
    char line[MAX], result;

    while (fgets(line, sizeof(line), in_file)) {
        len = strlen(line);
        for (i = 0; i < len; i  ) {
            freq[line[i]]  ;
        }
    }
    while (fgets(line, sizeof(line), in_file)) {
        len = strlen(line);
        for (i = 0; i < len; i  ) {
            if (max < freq[line[i]]) {
                max = freq[line[i]];
                result = line[i];
            }
        }
    }

    printf("Most frequent char = %c\n", result);
    return;
}

CodePudding user response:

Your initial loop is almost correct: you should convert the char to an unsigned char to avoid undefined behavior on negative char values on platforms where char is signed.

The second loop is incorrect: there is no need to read from the file, just iterate over the freq array to find the largest count.

Here is a modified version:

#include <limits.h>
#include <stdio.h>

void replace_most_freq(const char *filename, char newc, FILE *destination) {
    FILE *in_file = fopen(filename, "r");
    if (!in_file) {
        fprintf(stderr,
                "Error(replace_most_freq): Could not open file %s\n", filename);
        return;
    }
    int c, max, maxc;
    int freq[UCHAR_MAX] = { 0 };

    while ((c = getc(in_file)) != EOF) {
        freq[c]  ;
    }
    max = freq[maxc = 0];
    for (c = 1; c < UCHAR_MAX; c  ) {
        if (max < freq[c])
            max = freq[maxc = c];
    }
    printf("Most frequent char = %c (%d)\n", max, max);
    rewind(in_file);
    while ((c = getc(in_file)) != EOF) {
        if (c == maxc)
            c = newc;
        putc(c, destination);
    }
}

CodePudding user response:

You can read file in much larger chunks:


#define BUFFSIZE     (4*1024*1024)

int findMax(const size_t *, size_t);

int  replace_most_freq(const char *filename, char c, FILE *destination) {
    int result = 1;
    FILE *fi ;
    size_t freq[256] = { 0 };
    size_t dataChunkLength;
    long fileLength;
    unsigned char *databuff = malloc(BUFFSIZE);

    if(!databuff)
    {
        result = -2;
        goto function_exit;
    }

    fi = fopen(filename, "r");
    if (!fi) 
    {
        result = -1;
        goto function_exit;
    }

    if (fseek(fi, 0, SEEK_END) == -1)
    {
        result = -3;
        goto function_exit;
    }

    fileLength = ftell(fi);
    if (fileLength == -1)
    {
        result = -4;
        goto function_exit;
    }

    if (fseek(fi, 0, SEEK_SET) == -1)
    {
        result = -3;
        goto function_exit;
    }

    while(fileLength)
    {
        if(fileLength <= BUFFSIZE) dataChunkLength = fileLength;
        else dataChunkLength = BUFFSIZE;

        size_t bytesRead = fread(databuff, 1, dataChunkLength, fi);
        if(bytesRead != dataChunkLength)
        {
            if(feof(fi) || ferror(fi))
            {
                result = -4;
                goto function_exit;
            }
        }
        for(size_t index = 0; index < bytesRead; index  )
        {
            freq[databuff[index]]  ;
        }
        fileLength -= bytesRead;
    }

    int mostFrequent;

    printf("The most freq char is 0xx\n", mostFrequent = findMax(freq, 256));



    function_exit:
    free(databuff);
    if (fi) fclose(fi);
    return result;

}
  •  Tags:  
  • c
  • Related