K&R гистограмма длины слов

Я делаю упражнения 1-13 K&R. Проблема состоит в том, чтобы напечатать гистограмму длин слов во входных данных. Это более простая задача — распечатать гистограмму с горизонтальными полосами. Это то, что я придумал. Есть лучший способ сделать это? Есть ли баги?

#include <stdio.h>

#define MAXLEN 10

int main(){
    int c,length;
    int hist[MAXLEN+1];

    length=0;
    for(int i=0;i<MAXLEN+1;i++) hist[i]=0;

    while((c=getchar())!=EOF){
        if((c==' ' || c=='t' || c=='n') && length){
            if(length>MAXLEN)
                hist[MAXLEN]++;
            else
                hist[length-1]++;
            length=0;
        }
        else if(c!=' ' && c!='t' && c!='n')
            length++;
    }
    //to deal with situations in which input doesn't end in a space or newline or tab
    if(length>MAXLEN)
        hist[MAXLEN]++;
    else if(length)
        hist[length-1]++;

    //printing the histogram horizontally
    putchar('n');
    for(int i=0;i<MAXLEN;i++){
        printf("%3d|",i+1);
        for(int j=0;j<hist[i];j++) putchar('x');
        putchar('n');
    }
    printf(">%d|",MAXLEN);
    for(int i=0;i<hist[MAXLEN];i++) putchar('x');
    putchar('n');
}

1 ответ
1

Объявление и инициализация переменных за один раз

Вы можете инициализировать значение одновременно с его объявлением. Это работает даже для structs и массивы. Например:

int main() {   
    int c = 0;
    int length = 0;
    int hist[MAXLEN+1] = {0}; // Initializes all elements to 0

    while ((c = getchar()) != EOF) {
        ...

Использовать isspace()

Вместо того, чтобы вручную проверять пробелы, табуляции и символы новой строки, используйте isspace() за <ctype.h>.

Разделите свой код на несколько функций

Даже для такой простой программы, как эта, полезно разделить код на несколько функций и максимально снизить ответственность каждой функции. Так, например, main() может быть сокращено до:

int main() {
    int hist[MAXLEN + 1] = {0};

    build_histogram(hist, MAXLEN);
    print_histogram(hist, MAXLEN);
}

потом build_histogram() можно было бы написать так:

static void build_histogram(int hist[], size_t hist_size) {
    int c;
    int length = 0;

    while ((c=getchar())!=EOF) {
        if (isspace(c)) {
            add_word(hist, hist_size, length);
            length = 0;
        } else {
            length++;
        }
    }

    add_word(hist, hist_size, length);
}

Так что его основная функция — поиск слов. потом add_word() выполняет фактическую работу по записи длины слова в гистограмме:

static void add_word(int hist[], size_t hist_size, size_t length) {
    if (length > hist_size)
        hist[hist_size]++;
    else if (length)
        hist[length - 1]++;
}

Вы можете использовать аналогичный подход для print_histogram().

  • Я хотел бы использовать все это, и я тоже знаю функции, но на этом этапе книги этим функциям не учили.

    — аритра


  • Я заметил, что ты написал for (int i=0; ...), то есть не K&R C, а C99. Вы уверены, что используете только те возможности, о которых говорится в книге, и имеет ли это значение в долгосрочной перспективе?

    — Г. Сон

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *