Output error - C language

2

Good afternoon,

Currently studying Language C and I am faced with a situation that has stuck in the progress of studies, I have made a structure that receives registration and address. The compiler does not report errors, but when it behaves strangely, not allowing all data to be received, the expected output on each line should be:
Name->
Age- >
Street- >

Where each line points to the data to be filled after typing and give enter.The error occurs after informing age:
Name-> Jeferson
Age- > 35
Street- >

In the same line as Street- strong>. Follow the code below, and I appreciate any help you may have.

#include<stdio.h>
#include<stdlib.h>

struct endereco{
char rua[50];
int numero;
};
struct cadastro{
char nome[50];
int idade;
struct endereco ender;
};
int main(int argc, char const *argv[])
{
struct cadastro c;
//Lê do teclado uma string e armazena no campo nome
printf("Nome-> ");
gets(c.nome);

//Lê do teclado um valor inteiro e armazena no campo idade
printf("Idade-> ");
scanf("%d",&c.idade);

//Lê do teclado uma string
//e armazena no campo rua da variavel ender
printf("Rua-> \n ");
gets(c.ender.rua);

//Lê do teclado um valor inteiro
//e armazena no campo numero da variavel ender
printf("Numero-> ");
scanf("%d",&c.ender.numero);


system("pause");
return 0;
}
    
asked by anonymous 03.06.2018 / 22:46

2 answers

4

The problem has to do with the intersection of gets and scanf , and in this case gets is reading only the line break that got from reading c.idade leaving text to read, which is picked up by the following readings.

However, before starting I want to leave here the message given by the compiler, which is relevant:

  

main.c | 18 | warning: the 'gets' function is dangerous and should not be used.

The gets function is dangerous and should not be used! It is also difficult to work with other types of reading such as scanf . The safest alternative would be to fgets , but you can also resolve with scanf if you use the appropriate formatter.

Reading with scanf

To read with scanf to the end of the line you can use "%[^\n]" , or specify the size with "%50[^\n]" .

With this your readings would look like this:

printf("Nome-> ");
scanf("%50[^\n]",c.nome); //ler ate ao fim da linha

printf("Idade-> ");
scanf("%d",&c.idade);

printf("Rua-> ");
scanf(" %50[^\n]",c.ender.rua);
//     ^-----este espaço consome a quebra de linha da leitura anterior

printf("Numero-> ");
scanf("%d",&c.ender.numero);

See this example working on ideone

Reading with fgets

For fgets , a little more processing is required because the line break is read and stored in the variable. This then causes a strange effect of "Enters" more when it will show its values.

Reading is done with:

fgets(string, tamanho, stdin);

The broken line that is left over is removed through strcspn , which gives it the position where it is or the string size if it does not exist:

string[strcspn(string, "\n")] = 0;

Applying to your code would look like this:

printf("Nome-> ");
fgets(c.nome, 50, stdin); //leitura com fgets
c.nome[strcspn(c.nome, "\n")] = 0; //remoção do \n

printf("Idade-> ");
scanf("%d",&c.idade);

printf("Rua-> ");
fgetc(stdin); //ler a quebra de linha da leitura anterior
fgets(c.ender.rua, 50, stdin); //leitura com fgets
c.ender.rua[strcspn(c.ender.rua, "\n")] = 0; //remoção do \n

printf("Numero-> ");
scanf("%d",&c.ender.numero);

See this example also in Ideone

Ducting the functions used:

04.06.2018 / 00:26
2

Actually what was complicating was the statement gets, I recommend reading the colleague's explanation below, but anyway here is an alternative to your code without many changes.

#include<stdio.h>
#include<stdlib.h>

struct endereco{
    char* rua[50];
    int numero;
};
typedef struct cadastro{
    char nome[50];
    int idade;
    struct endereco ender;
}cadastro;
int main(int argc, char const *argv[])
{
    cadastro c;
    //Lê do teclado uma string e armazena no campo nome
    printf("Nome-> ");
    scanf("%s", &c.nome);

    //Lê do teclado um valor inteiro e armazena no campo idade
    printf("Idade-> ");
    scanf("%d",&c.idade);

    //Lê do teclado uma string
    //e armazena no campo rua da variavel ender

    printf("Rua-> ");
    scanf("%s", &c.ender.rua);

    //Lê do teclado um valor inteiro
    //e armazena no campo numero da variavel ender
    printf("Numero-> ");
    scanf("%d",&c.ender.numero);
/*
    printf("%s", c.nome);
    printf("\n%d", c.idade);
    printf("\n%s", c.ender.rua);
    printf("\n%d\n", c.ender.numero);
*/
    system("pause");
    return 0;
}
    
04.06.2018 / 00:48