Я делаю упражнения 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 ответ
Объявление и инициализация переменных за один раз
Вы можете инициализировать значение одновременно с его объявлением. Это работает даже для 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. Вы уверены, что используете только те возможности, о которых говорится в книге, и имеет ли это значение в долгосрочной перспективе?— Г. Сон