Подсчет символов. Подсчет символов Си. Символов в строке на C + построить гистограмму.

February 1, 2019 23:57

Цель данной лабораторной работы: написать программу для подсчета количества символов в файле. Построить график соотношения символов. Учитывать все буквы и символы (a-z, A-Z, 0-9, !@#$%^&*()_+<>?,./| и т.д.). В качестве языка для реализации можно использовать любой удобный.

Скриншот работы программы (нажмите на изображение, чтобы увидеть полностью):

Пример работы программы
Пример работы программы

Параметры запуска:

  • открыть консоль;
  • ввести название полученного скомпилированного .exe и название файла .txt, например (lab.exe text.txt);
  • $: lab.exe text.txt.

Реализация программы на языке программирования C (си):

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define NUMBER_POSIBLE_CHARS 256


void fatal(const char *where) {
    fprintf(stderr, "[!]\t%s : %s\n", where, strerror(errno));
    exit(EXIT_FAILURE);
}

size_t getFileSize(const char *filename) {
    FILE *file = fopen(filename, "rb");
    size_t file_size;

    if (!file) {
        fatal("getFileSize()");
    }

    fseek(file, 0, SEEK_END);
    file_size = ftell(file);
    fclose(file);

    return file_size;
}

char *readFile(const char *filename) {
    FILE *file;
    char *buf;
    size_t file_size;

    file_size = getFileSize(filename);
    file = fopen(filename, "rb");
    buf = malloc(file_size);
    fread(buf, file_size, 1, file);

    fclose(file);

    return buf;
}

unsigned *getFreqOfSymbolsMap(const char* filename) {
    char *dump = readFile(filename);
    size_t dump_len = getFileSize(filename);

    unsigned *map = calloc(NUMBER_POSIBLE_CHARS, sizeof(unsigned));

    for (size_t i = 0; i < dump_len; ++i) {
        map[(int)dump[i]]++;
    }

    free(dump);

    return map;
}

void printGistogram(unsigned *alpha) {
    for (int i = 0; i < NUMBER_POSIBLE_CHARS; ++i) {
        if (alpha[i] != 0) {
            if (i == 10) {
                printf("\\x%3d {\'\\n\'} :", i);
            } else
                printf("\\x%3d {\'%c\'} (%d):", i, i, alpha[i]);
            for (unsigned j = 0; j < alpha[i]; ++j) {
                printf("%c", '#');
            }
            printf("\n");
        }
    }
}

int main(int argc, const char *argv[]) {
    if (argc > 1) {

        unsigned *alpha = getFreqOfSymbolsMap(argv[1]);
        printGistogram(alpha);

        free(alpha);

    } else {
        fatal("Wrong number of arguments.");
    }

    exit(0);
}