scanf para não exceder saturação de buffer
Pergunta
Eu tenho um buffer e eu não quero que o usuário digite mais caracteres do que o buffer pode conter (para evitar uma saturação de buffer).
Eu estou usando scanf
e ter feito assim:
char buffer[30] = {'\0'};
scanf("%30s", buffer);
No entanto, eu sei que eu sou protegido se o usuário inserir mais de 30. No entanto, se o usuário inserir mais de 30, será o buffer ser nulo terminada?
Solução
scanf()
com especificador de conversão de "% s" adiciona um caractere de terminação nula para o buffer.
Mas , você está pedindo 30 caracteres, o que realmente significa 31 e só tem espaço para 30. Você deve usar uma largura de campo máximo de 29.
char buffer[30] = {'\0'};
scanf("%29s", buffer);
Além disso, note que o "%c"
especificador de conversão funciona muito bem como "%s"
, mas não adiciona o caractere de terminação nula e não faz espaço descarte a partir da entrada. Dependendo do que você espera, pode ser melhor do que usar "% s".
char buffer[30] = {'\0'};
scanf("%29c", buffer);
buffer[29] = '\0';
Outras dicas
A partir do scanf
manual:
s encontra uma sequência de caracteres não-branco-espaciais; nas próximas apontador deve ser um ponteiro para serviço doméstico, e a matriz tem de ser suficientemente grande para aceitar toda a sequência e o caráter de terminação NUL. o cadeia de entrada pára no espaço em branco ou no campo largura máxima, o que ocorrer primeiro.
Você está invocando UB. Tente:
#define str(x) #x
#define xstr(s) str(x)
#define BUFSIZE 30
char buffer[ BUFSIZE + 1 ];
scanf("%" xstr(BUFSIZE) "s", buf);
Para ignorar qualquer coisa além BUFSIZE
personagens suprimir atribuição:
scanf("%" xstr(BUFSIZE) "s%*", buf);
Você também deve verificar se o usuário inseriu retorno / nova linha e terminar scanf
se ele tem:
scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
e é uma boa prática para verificar valores de retorno, assim:
int rc = scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
e, finalmente, verificar se o que há qualquer coisa à esquerda (como a nova linha, e consumi-lo):
if (!feof(stdin))
getchar();
Você terá uma saturação de buffer porque você não tem permissão para o personagem de terminação NUL. Declare seu tampão como este:
char buffer[31];
e você vai ficar bem.