Desafio C
Concatenação segura e verificação de overflow
Enunciado
Escreva um programa que leia dois nomes (máximo 20 caracteres cada) e os concatene em um buffer de 30 caracteres. Use fgets para ler, remova o '\n' e verifique se a concatenação cabe. Se não couber, exiba uma mensagem de erro; caso contrário, mostre o nome completo e seu comprimento.
Requisitos
- Use
fgetspara ler cada nome, removendo o caractere de nova linha. - Verifique se a soma dos comprimentos + 1 (terminador) é menor ou igual a 30.
- Use
strncatousnprintfpara concatenar com segurança. - Imprima
Nome completo: <resultado>eComprimento: <n>ouErro: nome muito longo.
Código inicial
#include <stdio.h>
#include <string.h>
int main(void) {
char nome1[21], nome2[21];
char completo[30];
// Leia, remova '\n', verifique e concatene
return 0;
}
Saída esperada
Nome completo: Maria Silva
Comprimento: 11
Ver dica
Após fgets, use strcspn(nome, "\n") para encontrar a posição do '\n' e substitua por '\0'.
Mostrar solução
#include <stdio.h>
#include <string.h>
int main(void) {
char nome1[21], nome2[21];
char completo[30];
// Leitura segura com fgets
fgets(nome1, sizeof(nome1), stdin);
fgets(nome2, sizeof(nome2), stdin);
// Remove o '\n' do final, se existir
nome1[strcspn(nome1, "\n")] = '\0';
nome2[strcspn(nome2, "\n")] = '\0';
size_t len1 = strlen(nome1);
size_t len2 = strlen(nome2);
// Verifica se cabe no buffer completo (incluindo espaco e terminador)
if (len1 + 1 + len2 + 1 > sizeof(completo)) {
printf("Erro: nome muito longo\n");
return 1;
}
// Copia o primeiro nome e concatena com espaco e segundo nome
strcpy(completo, nome1);
strcat(completo, " ");
strcat(completo, nome2);
printf("Nome completo: %s\n", completo);
printf("Comprimento: %zu\n", strlen(completo));
return 0;
}
Passo a passo
- Declaramos
nome1[21]enome2[21]para ler até 20 caracteres +'\0'. fgetslê a linha inteira, incluindo o'\n', e garante o terminador.strcspn(nome, "\n")retorna o índice do'\n'; substituímos por'\0'para remover a quebra de linha.- Calculamos
len1elen2comstrlen. - Verificamos se
len1 + 1 (espaço) + len2 + 1 (terminador)cabe emsizeof(completo). Se não, exibimos erro e saímos. - Copiamos
nome1paracompletocomstrcpye concatenamos espaço enome2comstrcat. Como já verificamos o tamanho, é seguro. - Imprimimos o resultado e o comprimento.
Por que funciona
A verificação prévia evita buffer overflow. fgets limita a leitura ao tamanho do buffer, e a remoção do '\n' garante que a string não tenha caracteres indesejados. strcat é seguro porque o destino tem espaço suficiente comprovado pela verificação.
Erros comuns
- Não remover o
'\n': o nome completo teria uma quebra de linha no meio. - Esquecer de verificar o tamanho:
strcatpode estourar o buffer. - Usar
scanf("%s", nome)sem limite: risco de overflow se a entrada for maior que o buffer. - Não incluir o espaço na conta do tamanho: a verificação pode passar, mas a concatenação falhar.
Outra forma de resolver
Usar snprintf(completo, sizeof(completo), "%s %s", nome1, nome2) é mais direto e já trunca se necessário. Prefira snprintf para concatenações simples.
Saída esperada
Nome completo: Maria Silva
Comprimento: 11