Como usar a função Gets() no Ubuntu?

1. Como usar a função Gets() no Ubuntu?

Perfil removido
removido

(usa Nenhuma)

Enviado em 20/04/2016 - 19:29h

Galera, sei que a função Gets não é recomendada e talz, mas meu professor falou que é obrigatório utilizar na matéria dele por enquanto por que senão ele ia tirar nota, a matéria é Logica de Programação, fazer o que né?
Tem alguma forma de forçar o Ubuntu a aceitar o uso da função Gets?


  


2. Re: Como usar a função Gets() no Ubuntu?

Uilian Ries
uilianries

(usa Linux Mint)

Enviado em 21/04/2016 - 00:46h

Questione o seu professor, o porquê de usar gets()

gets() foi dado como obsoleto e compiladores não tão velhos, irão alertar sobre isso.
Ele tem uma fragilidade por ler a entrada de caracteres até um batente, no caso '\0'.
A string passada para armazenar a entrada de caracteres, deve ser suficiente para suportar todos caracteres da entrada.
Veja o exemplo:


#include <stdio.h>

int main(void)
{
char nome [16] = {0};

printf("Digite o seu nome: ");
gets(nome);
printf("Bem-vindo %s\n", nome);

return 0;
}


Durante a execução teremos:

Digite o seu nome: Uilian Ries
Bem-vindo Uilian Ries


Okay, tudo funcionou muito bem.
Mas o que acontece quando eu coloco uma string maior?


Digite o seu nome: Nome Muito Grande Para Caber Na String
Bem-vindo Nome Muito Grande Para Caber Na String
*** stack smashing detected ***: ./Gets terminated
Aborted


Ops! O compilador detectou um transbordamento da pilha, pois o meu nome é maior do que a string e como
resposta, lançou um sinal para abortar o processo.
Você pode obter mais informações lendo o manual:

$ man gets


O meio mais comum de evitar essa situação, é utilizando fgets:

#include <stdio.h>

int main(void)
{
char nome [16] = {0};

printf("Digite o seu nome: ");
if (fgets(nome, sizeof(nome), stdin) == NULL) {
printf("ERRO: Impossivel capturar o seu nome.");
return 1;
}
printf("Bem-vindo %s\n", nome);

return 0;
}


Agora, mesmo usando um nome maior, não teremos o transbordamento:

Digite o seu nome: Nome Muito Grande Para Ser Lido
Bem-vindo Nome Muito Gran





3. Re: Como usar a função Gets() no Ubuntu?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 21/04/2016 - 11:59h

A função gets não está simplesmente "depreciada": ela foi REMOVIDA da biblioteca padrão do C desde a publicação da última versão do padrão da linguagem, em 2011. A função que o seu professor está exigindo não é nem mesmo suportada por compiladores com menos de cinco anos.

Infelizmente, professores ruins são fatos da vida, e as escolas, por ruindade ou por corporativismo -- afinal o professor, mesmo quando ruim, é antes de tudo um "companheiro" da "categoria" --, não costumam se movimentar no sentido de obrigar esses charlatães a melhorar suas posturas e atualizar seus conhecimentos. Assim sendo, eu sugiro que você obedeça à requisição do seu professor (mesmo sendo meio cretina) e, ao mesmo tempo, avalie se vale a pena comunicar à coordenação do curso a inadequação do conteúdo da matéria e sua desconexão com a realidade (note que eu falo em reclamar do conteúdo, não do professor, para ter mais chances de ser uma queixa que se aproveite).

"Enquanto isso, na Sala da Justiça", você pode experimentar embutir no seu código artifícios que, ao mesmo tempo, permitam-lhe satisfazer a exigência do professor e a dos compiladores modernos, ao mesmo tempo em que emite discretamente o aviso de que você sabe que está sendo obrigado a fazer besteira (mas note que, dependendo do grau de recalque do professor, até isso pode ser perigoso).

EDIT:
// Alternativa 1: criar uma versão alternativa e privativa de gets(),
// copiando inclusive os bugs da gets() original.

/* Modo de contornar reclamação sobre gets() em alguns sistemas (e.g. Ubuntu Linux). */
static char *my_gets(char *bogus){
int c; // int, não char!
int n=0;
while((c=getchar())!=EOF && c!='\n')
bogus[n++]=c;
bogus[n]='\0';
return n==0 && c==EOF? NULL: bogus;
}
#define gets(x) my_gets(x)


// Alternativa 2: Se você garantir que sempre vi chamar gets() com arrays
// de char, e nunca com ponteiros. Com esta versão, não se permite a
// leitura de mais caracteres do que o tamanho do array, o que a faz
// funcionalmente diferente da gets() original.

/*
Modo de contornar reclamação sobre gets() em alguns sistemas (e.g. Ubuntu Linux).
A implementação evita o buffer overrun da gets() original, interrompendo a leitura
antes do fim de linha, se necessário.
*/
static char *my_gets(char *str, size_t strsize){
int c; // int, não char!
int n=0;
if(strsize==0)
return NULL;
--strsize;
while(n<strsize && (c=getchar())!=EOF && c!='\n')
str[n++]=c;
str[n]='\0';
return n==0 && c==EOF? NULL: str;
}
#define gets(x) my_gets(x, sizeof x/sizeof x[0])


// Alternativa 3: Semelhante à anterior, mas aceita argumento ponteiro também.
// Há, porém, dois problemas:
// 1) quando o argumento é ponteiro, não dá para inferir automaticamente o tamanho
// da área apontada, e por isso a função vira gets(), com possibilidade de overrun;
// 2) como a detecção do ponteiro é feita com base no tamanho do argumento, um array
// com nº de elementos igual ao tamanho de um ponteiro é interpretado como se fosse
// ponteiro, logo sujeito a overrun também.

/*
Modo de contornar reclamação sobre gets() em alguns sistemas (e.g. Ubuntu Linux).
A implementação tenta, se possível, evitar o buffer overrun da gets() original, inter-
rompendo a leitura antes do fim de linha, se necessário.
*/
static char *my_gets(char *str, size_t strsize){
int c; // int, não char!
int n=0;
if(strsize==0)
return NULL;
--strsize;
while(n<strsize && (c=getchar())!=EOF && c!='\n')
str[n++]=c;
str[n]='\0';
return n==0 && c==EOF? NULL: str;
}
#define gets(x) my_gets((x), sizeof (x)!=sizeof(char *)? sizeof (x)/sizeof (x)[0]: INT_MAX)


// Alternativa 4: em C++.

// Função polimórfica com array passado por referência (invocada
// se o argumento da macro, abaixo, for um array).
template <size_t strsize> char *my_gets(char (&str)[strsize]){
cin.getline(str, strsize);
return cin.failbit()? nullptr: str;
}

// Função polimórfica com ponteiro passado por referência (invocada
// se o argumento da macro, abaixo, não for um array).
char *my_gets(char *const &ptr){
cin.getline(ptr, numeric_limits<streamsize>::max());
return cin.failbit()? nullptr: ptr;
}

#define gets(x) my_gets(x)


Por fim, há, sim, como fazer o Ubuntu aceitar o uso de gets(). Se você usa o GCC, na hora de compilar, você pode dizer que quer usar o padrão ISO do C de 1990 (“-std=c90” (ou “-std=gnu90”, se pretender usar extensões exclusivas da GNU além do padrão de 1990). Pode também usar c99/gnu99 para o padrão de 1999, mas aí já vai receber avisos de que gets() é obsoleta. Você pode ignorar tais avisos, ou pode desabilitá-los, por meio da opção “-Wno-deprecated-declaration”.

Já a mensagem de aviso que vem do linker é mais difícil de desabilitar. Se você não quiser simplesmente ignorá-la, pode seguir a sugestão dada em http://stackoverflow.com/questions/3409448/how-do-you-suppress-gcc-linker-warnings.


4. Re: Como usar a função Gets() no Ubuntu?

Perfil removido
removido

(usa Nenhuma)

Enviado em 21/04/2016 - 17:50h

Então, ele avisou que a função não era mais usada, mas que era para a gente usar por que ainda estamos no inicio da matéria.. (tem gente que não sabe mesmo ainda programar)..

Pensando bem, no Windows o gets ainda funciona, acho que vou ter que instalar o Codeblocks (que ele também obrigou a usar) no Windows e fazer a lista por lá.. Mas vou deixar o tópico aberto ainda para caso alguém tenha alguma solução.. Obrigado a todos que responderam acima.. :)


5. Re: Como usar a função Gets() no Ubuntu?

Perfil removido
removido

(usa Nenhuma)

Enviado em 21/04/2016 - 18:35h

Deve estar usando algum compilador tipo aquele da Borland© do tempo do MS-DOS©.

----------------------------------------------------------------------------------------------------------------
# apt-get purge systemd (não é prá digitar isso!)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden



6. Re: Como usar a função Gets() no Ubuntu?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 22/04/2016 - 04:18h

O prometido comentário na minha postagem anterior foi finalmente feito. Dê uma olhada lá.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts