Output error - C language

Asked

Viewed 895 times

3

Good afternoon,

Currently studying Language C and I come across a situation that has locked in the progress of studies,I made a structure that receives registration and address. The compiler does not accuse errors, but when the wheel behaves strangely not allowing to receive all the data, the expected output on each line should be:
Name->
Age->
Street->
Number->

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

In the same line of Street-> soon after appears Number->,tried to put the " n" but it also jumps straight to Number->.
Follow the code, and I appreciate any help offered.

#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;
}

2 answers

5


The problem has to do with the interim gets and scanf, and in this case the gets is only reading the line break left from the c.idade leaving the text unread, which is caught 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 function gets is dangerous and should not be used! Moreover it is difficult to get it to work with other types of reading like scanf. The safest alternative would be to fgets, but can also solve with scanf if using the appropriate formatter.

Reading with scanf

To do the reading with scanf up 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

To the fgets It takes a little more treatment, because the line break is read and stored in the variable. This later causes an extra "Enters" effect when it shows its values.

The reading is done with:

fgets(string, tamanho, stdin);

The line break that got the most is removed through strcspn which gives you the position where it is or the size of the string 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

Evaluation of the functions used:

  • Thank you so much for the "class", it was enough to make me change study material, by the way it is not at all enlightening. Thanks for the notes.

2

Really what was complicating was the instruction 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;
}

Browser other questions tagged

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