Как бороться с переполнением буфера в C? - PullRequest
0 голосов
/ 22 апреля 2019

Почему этот код пропустит цикл несколько раз, если длина ввода больше 2?

Кажется, это связано с переполнением буфера. Но можно ли очистить входной буфер в конце цикла и как?

#include <stdio.h>

int main(void)
{
    char in[2];
    while (in[0] != 'q') {
        puts("Enter: ");
        fgets(in, 3, stdin);
    }
    return 0;
}

Я хочу попросить пользователя ввести некоторую строку в каждом цикле.

1 Ответ

0 голосов
/ 22 апреля 2019

Во-первых, ваш буфер недостаточно велик, чтобы содержать строку из 2 символов. К строкам в C нужно добавить дополнительный '\ 0', чтобы отметить конец. Во-вторых, fgets оставит символы во входном буфере, когда входная строка длиннее, чем переданный ей буфер. Вам нужно использовать эти символы перед повторным вызовом fgets.

Вот функция, похожая на fgets в том, что она будет читать только buffer_len - 1 символов. И он также будет потреблять все символы до новой строки или EOF.

int my_gets(char *buffer, size_t buffer_len)
{
    // Clear buffer to ensure the string will be null terminated
    memset(buffer, 0, buffer_len);

    int c;
    int bytes_read = 0;
    // Read one char at a time until EOF or newline
    while (EOF != (c = fgetc(stdin)) && '\n' != c) {
        // Only add to buffer if within size limit
        if (bytes_read < buffer_len - 1) {
            buffer[bytes_read++] = (char)c;
        }
    }
    return bytes_read;
}

int main(void)
{
    char in[3];  // Large enough for a 2 char string

    // Re-arranged to do/while
    do {
        puts("Enter: ");
        my_gets(in, sizeof(in));  // sizeof(in) == 3
    } while (in[0] != 'q');
    return 0;
}
...