Supporter - Byte paulosgf Posted August 25, 2018 Supporter - Byte Posted August 25, 2018 Pessoal, estou com um problema que talvez seja simples para alguns de vcs, mas como não tenho prática em C, estou com dificuldades. Comecei o keygenme da aula 17 CERO sugerido pelo Fernando que recebe um nome e converte para maiúsculo. E justo nesta parte ele estoura o buffer. O que pode estar errado? [ paulosgf /home/paulosgf/crack/keygenme ] $ cat keygenme.c #include <stdio.h> #include <ctype.h> int main(void) { char *str; printf("Nome: "); scanf("%s", str); while (*str != '\0') { *str = toupper((unsigned char) *str); str++; } printf("%s\n", str); return 0; } [ paulosgf /home/paulosgf/crack/keygenme ] $ gcc -o keygenme keygenme.c [ paulosgf /home/paulosgf/crack/keygenme ] $ ./keygenme Nome: paulo Falha de segmentação
fredericopissarra Posted August 26, 2018 Posted August 26, 2018 scanf() recebe, no caso do conversor %s, o ponteiro do buffer que receberá os caracteres... Ele não alocará o buffer pra você. Se você não sabe o tamanho do buffer ou não quer "gastar" espaço à toa, recomendo o uso de getline(): // Devolve ponteiro contendo a string lida ou NULL se houve algum erro. // OBS: O buffer precisará ser liberado com free(), na rotina chamadora para não causar // memory leakage. char *getstring(void) { char *p = NULL, *q; size_t size = 0; if ( getline( &p, &size, stdin ) == -1 ) return NULL; // Livra-se do \n no final... if ( q = strchr( p, '\n' ) ) *q = '\0'; return p; }
Supporter - Byte paulosgf Posted August 27, 2018 Author Supporter - Byte Posted August 27, 2018 Obrigado pela dica fredericopissarra! Eu ainda estava tendo problemas com esse trecho, que apagava o buffer: while (*str != '\0') { *str = toupper((unsigned char) *str); str++; } mas, enfim consegui resolver trocando por um laço for. O código ficou assim: b38990@lseo:~/crack/C$ cat pegastring.c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> int main(void) { char *buffer = NULL, *caractere; size_t tamanho = 0; int i; buffer = (char *)malloc(tamanho * sizeof(char)); if( buffer == NULL) { perror("Impossivel alocar buffer"); exit(1); } printf("Nome: "); if (getline(&buffer,&tamanho,stdin) == -1) return NULL; if ( caractere = strchr( buffer, '\n' ) ) *caractere = '\0'; for (i=0; i<=strlen(buffer); i++) { buffer = toupper(buffer); } printf("Nome: %s\n",buffer); return(0); } b38990@lseo:~/crack/C$ gcc -o pegastring pegastring.c pegastring.c: In function ‘main’: pegastring.c:20:9: warning: return makes integer from pointer without a cast [-Wint-conversion] return NULL; ^ b38990@lseo:~/crack/C$ ./pegastring Nome: paulo Nome: PAULO Abraço!
fredericopissarra Posted August 27, 2018 Posted August 27, 2018 Quatro detalhes... linha 20 (return NULL) é o que está causando o aviso (main espera retornar int, não char *); Segundo... getline() aloca o buffer automaticamente se o ponteiro for NULL (como é o caso) e o tamanho for 0. Note que você passa o ponteiro para o ponteiro e um ponteiro para o tamanho porque eles serão atualizados pela função - Ou seja, esse malloc() ai é desnecessário e, no contexto, ERRADO; Terceiro: É interessante livrar-se do buffer alocado com free() antes de sair do processo (embora o encerramento vá fazer isso por você); Quarto... O loop estava correto (talvez você estivesse atualizando buffer e ai estivesse o erro. Eu o substituiria por: for (char *p = buffer; *p; p++) *p = toupper(*p);
Supporter - Byte paulosgf Posted August 28, 2018 Author Supporter - Byte Posted August 28, 2018 O free(buffer); eu tinha esquecido. O resto ocorreu conforme vc previu: removi a alocação com malloc() e troquei por return -1; na getline(), ambos sem problemas! Mais uma vez obrigado fredericopissarra! É bom saber que temos aliados que entendem dispostos a ajudar!
Recommended Posts
Archived
This topic is now archived and is closed to further replies.