printf выводит слишком часто - PullRequest
       36

printf выводит слишком часто

3 голосов
/ 02 августа 2020
#include <stdio.h>


void fillline(char *line, char c, int len){
    for(int i = 0; i<len-1; i++)
        line[i] = c;
    line[len-1] = '\n';
    line[len] = '\0';
}

int main() {
    
    char xs[4][30];
    fillline(xs[0], '-', 30);
    fillline(xs[1], '(', 30);
    fillline(xs[2], ')', 30);
    fillline(xs[3], 'Z', 30);

    printf("%s", xs[0]);
    printf("%s", xs[1]);
    printf("%s", xs[2]);
    printf("%s", xs[3]);
       
}

Здравствуйте, C -программирование newb ie здесь. У меня проблема с приведенным выше кодом. Я ожидаю

-----------------------------
(((((((((((((((((((((((((((((
)))))))))))))))))))))))))))))
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

в качестве вывода командной строки, созданного из моего кода, но я получаю

-----------------------------
(((((((((((((((((((((((((((((
)))))))))))))))))))))))))))))
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
(((((((((((((((((((((((((((((
)))))))))))))))))))))))))))))
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
)))))))))))))))))))))))))))))
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

Что я делаю не так? Я пробовал fflush(stdout) и setbuf(stdout, NULL) (хотя я точно не уверен, что это проблема stdout).

Заранее спасибо.

Ответы [ 3 ]

5 голосов
/ 02 августа 2020

Проблема возникает по двум причинам.

  1. Строки не имеют нулевого терминатора. Использование его в качестве строки в printf("%s", xs[N]) вызывает неопределенное поведение.

  2. С

    line[len] = '\0';
    

    вы также пытаетесь записать '\0' в несуществующий 31-й элемент.

Обратите внимание, что индексирование массива начинается с 0, а не 1. Эта путаница и вызвала здесь вашу проблему.

Решение (я):

1.

Измените

void fillline(char *line, char c, int len) {
    for(int i = 0; i < len-1; i++)
        line[i] = c;
    line[len-1] = '\n';
    line[len] = '\0';
}

на

void fillline(char *line, char c, int len) {
    for(int i = 0; i < len-2; i++)
        line[i] = c;
    line[len-2] = '\n';
    line[len-1] = '\0';
}

OR

2 .

Уменьшить len перед использованием в l oop на 1.

void fillline(char *line, char c, int len) {
    len--;
    for(int i = 0; i < len-1; i++)
        line[i] = c;
    line[len-1] = '\n';
    line[len] = '\0';
}

OR

3.

Позвонить функция fillline с третьим аргументом значения 29, а не 30.

fillline(xs[0], '-', 29);
4 голосов
/ 02 августа 2020

Вы перезаписываете конец своего буфера.

void fillline(char *line, char c, int len){
    for(int i = 0; i<len-3; i++)
        line[i] = c;
    line[len-2] = '\n';
    line[len-1] = '\0';
}
1 голос
/ 02 августа 2020

Это не '\0' в конце строки из-за того, что вы пытаетесь записать поверх массива, это приведет к неопределенному поведению.

Иногда плохая идея не выполнять проверку привязки в C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...