Problem with gets and fgets

Asked

Viewed 1,297 times

4

I’m having problems with the gets function and fgets...

Always when I use them, the program skips the input, ie the user can not type the string, but it only works with scanf, just that I need to use the gets or fgets. I’ve used the function getchar(); whenever I use up let me type, but end up repeating, telling to record another again and again and again...

Below is the code:

int main()
{

    char s1[20];
    char s2[20];
    int escolha = 1;

    printf("*****************************\n");
    printf("*Menu de opções para strings*\n");
    printf("*****************************\n\n");
    printf("Primeiro informe seu nome por favor: ");
    gets(s1);

    do
    {
        printf("\n(1) Quer saber o tamanho de seu nome?\n");
        printf("(2) Que tal comparar seu nome com outro nome?\n");
        printf("(3) Quer unir seu nome com outro nome?\n");
        printf("(4) O que acha de seu nome invertido?\n");
        printf("(5) Quer saber quantas vezes a mesma letra aparece em seu nome?\n");
        scanf("%d", &escolha);
        system("cls");

        switch(escolha)
        {

        case 1:
            printf("A quantidade de caracters de seu nome é: %d", strlen(s1));
            break;

        case 2:
            printf("Digite um novo nome para comparar: ");
            fgets(s2, 20, stdin);
            break;

        default:
            printf("Opção inválida");
        }

    } while(escolha);
    return 0;
}
  • 2

    gets is considered obsolete, insecure, ugly and poorly seen. Do not use it. At most use fgets passing by stdin as an argument

2 answers

3


I suggest using always fgets, since it is something you are already using, and ensures that your program is never susceptible to Buffer Overflows.

Even when you have to read a whole like in case a opcao, can still read the content as string to a temporary buffer of size defined by you and interpret your integer either with sscanf or even atoi:

char buff[20];
fgets(buff, 20, stdin);
sscanf(buff, "%d", &escolha);

Note that the sscanf works like the scanf but starting from a string instead of the input stream.

Using fgets and sscanf, your program looks like this:

char s1[20];
char s2[20];
char buff[20]; //buffer de leituras
int escolha = 1;

printf("*****************************\n");
printf("*Menu de opções para strings*\n");
printf("*****************************\n\n");
printf("Primeiro informe seu nome por favor: ");
fgets(s1,20,stdin);
s1[strlen(s1)-1] = '\0'; //remover o \n que ficou da leitura com fgets

do {
    printf("\n(1) Quer saber o tamanho de seu nome?\n");
    printf("(2) Que tal comparar seu nome com outro nome?\n");
    printf("(3) Quer unir seu nome com outro nome?\n");
    printf("(4) O que acha de seu nome invertido?\n");
    printf("(5) Quer saber quantas vezes a mesma letra aparece em seu nome?\n");
    fgets(buff, 20, stdin); //agora fgets
    sscanf(buff, "%d", &escolha); //leitura do numero com sscanf
    system("cls");

    switch(escolha) {
    case 1:
        printf("A quantidade de caracters de seu nome é: %d", strlen(s1));
        break;
    case 2:
        printf("Digite um novo nome para comparar: ");
        fgets(s2, 20, stdin);
        s2[strlen(s2)-1] = '\0'; //remover o \n também
        break;
    default:
        printf("Opção inválida");
    }

} while(escolha);

You may want to abstract the reading logic to a function in order to simplify its various uses:

void lerString(char *stringLida){
    fgets(stringLida, 20, stdin);
    stringLida[strlen(stringLida)-1] = '\0';
}

That I would use:

lerString(s1);

See code working on Ideone

  • Very bakana, had already solved, but this way is much more professional!!! thanks!!!

  • I knew you had an answer saying if the fgets returned the line break or not. And in fact returns. Saved the answer I am writing

-1

It would not be the case to use fflush(stdin) after the following lines?

gets(s1);
fflush(stdin);

scanf("%d", & escolha);
fflush(stdin);

fgets(s2, 20, stdin);
fflush(stdin);

  • I managed to solve the problem, but thanks anyway, in fact it was almost that you quoted, only I had to put the fflush(stdin); before the gets!!! when I put it after the gets it was a mistake. in my humble opinion I think the problem is if I was using a switch, maybe the enter I gave when choosing an option was stored in the buffer...

  • Cool! It must be, this garbage issue in Buffer is complicated rsr... I’ve suffered a lot with this, especially with the while...

  • 3

    fflush() shall not be used to clean incoming buffers in the case stdin, and gets() should not be used because it does not adequately limit the amount of characters that the user can enter.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.