2017-02-20 39 views
1

Я работаю над книгой программирования K & R C, и я только что закончил упражнение 1-13, где вы печатаете гистограмму длин вводимых слов. Моя горизонтальная гистограмма прекрасна, но моя вертикальная гистограмма имеет знак «%», появляющийся в конце ее, и я не могу понять, почему это происходит. Вот цикл, который я думаю, что вызывает вопрос:Неожиданный «%» появляется в консоли

for (i = 0; i < array_length; i++) { 
    printf("%-4d", i + 1); 
} 

Если array_length 7, я буду иметь знак «%» после того, как 7-й позиции, как это:

   |   
       | |  
       | |  
       | |  
       | |  
       | |  
| | |  | |  
| | | | | |  
| | | | | | | 
| | | | | | | 
| | | | | | | 
1 2 3 4 5 6 7 % 

Если удалить этот цикл, вертикальные столбцы печатаются хорошо, я просто не получаю нумерацию ниже каждого из них.

Что здесь происходит? Насколько я могу судить, printf запускает лишнее время с данными мусора в «i», но я не могу понять, почему и как это происходит.

Я собираюсь с gcc на Ubuntu, если это имеет значение.

Вот полный код для справки:

#include <stdio.h> 

#define IN 1 
#define OUT 0 
#define ARRAY_SIZE 1000 

int main() { 

    int c, current_word_length, state, i, j, current_word, largest, array_length, top; 
    int word_lengths[ARRAY_SIZE]; 

    current_word_length = current_word = largest = 0; 
    state = OUT; 

    for (i = 0; i < ARRAY_SIZE; i++) { 
    word_lengths[i] = 0; 
    } 

    printf("Enter up to 1000 words and this program will calculate their length.\n"); 
    printf("Please enter a newline, tab, or space before the last word entered, then EOF to print summary.\n\n"); 

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

    if (c == ' ' || c == '\t' || c == '\n') { 
     if (state == IN) { 
     word_lengths[current_word++] = current_word_length; 
     if (current_word_length > largest) { 
      largest = current_word_length; 
     } 
     current_word_length = 0; 
     state = OUT; 
     } 
    } else { 
     state = IN; 
     current_word_length++; 
    } 

    } 

    array_length = current_word; 

    printf("\nWord Lengths Histogram Horizontal:\n\n"); 

    for (i = 0; i < array_length; i++) { 
    printf("%-4d: ", i + 1); 
    for (j = 0; j < word_lengths[i]; j++) { 
     printf("="); 
    } 
    printf("\n"); 
    } 

    printf("\nWord Lengths Histogram Vertical:\n\n"); 

    top = largest; 

    while (top > 0) { 

    for (i = 0; i < array_length; i++) { 
     if (word_lengths[i] >= top) { 
     printf("%-4c", '|'); 
     } else { 
     printf("%-4c", ' '); 
     } 
    } 

    printf("\n"); 

    top--; 
    } 

    for (i = 0; i < array_length; i++) { 
    printf("%-4d", i + 1); 
    } 

    return 0; 
} 

А вот то, что я ожидаю, происходит с помощью этой строки ввода "Bacon Ipsum Dolor Амет сосисок landjaeger ветчиной":

Enter up to 1000 words and this program will calculate their length. 
Please enter a newline, tab, or space before the last word entered, then EOF to print summary. 

Bacon ipsum dolor amet frankfurter landjaeger ham 

Word Lengths Histogram Horizontal: 

1 : ===== 
2 : ===== 
3 : ===== 
4 : ==== 
5 : =========== 
6 : ========== 
7 : === 

Word Lengths Histogram Vertical: 

       |   
       | |  
       | |  
       | |  
       | |  
       | |  
| | |  | |  
| | | | | |  
| | | | | | | 
| | | | | | | 
| | | | | | | 
1 2 3 4 5 6 7 
+10

Вы уверены, что% не только ваша оболочка подскажете? Добавьте 'printf (" \ n ");' или 'puts (" "); 'после вашего цикла (прямо перед' return 0; ') – nos

+0

ОК, это исправлено! Итак, я все еще многому учусь о том, как работает оболочка, можете ли вы объяснить мне, что произошло, или указать мне на ресурс, который это делает? –

+2

Ну, вы распечатали номера с 1 по 7, а затем ваша программа закончилась. Итак, оболочка начинается там, где вы перестали печатать. Распечатав новую строку перед вашей программой, оболочка запускает все, что она делает, в новой свежей строке, а не сразу после последнего номера 7. – nos

ответ

0

OK , как указано в комментариях nos и chqrlie, мне нужно добавить новую строку в конце моей программы, чтобы приглашение оболочки появлялось в новой строке ПОСЛЕ завершения программы.

Добавление putchar (вызов) в конце основной() фиксируется мой вопрос:

for (i = 0; i < array_length; i++) { 
    printf("%-4d", i + 1); 
    } 

    putchar('\n'); 

    return 0; 
} // end main() 
+1

Вы можете также использовать 'putchar ('\ n');' для вывода новой строки. Он имеет меньше накладных расходов, чем 'printf (" \ n ");'. –

+0

ОК, я обновлю это, спасибо! –

+0

@JonathanLeffler: Я согласен с принципом, но современные компиляторы генерируют один и тот же код для 'printf (" \ n ");', 'puts (" ");' и 'fputchar ('\ n');' – chqrlie