Ir ao conteúdo

Posts recomendados

Postado
#include<stdio.h>
#include<stdlib.h>
#define MAX 1000

typedef struct
{
    char nome[30];
    char endereco[50];
    int rg;
}cadastro;

typedef struct
{
    cadastro v[MAX];
    int n;
}vetor;


int main(void)
{
    vetor *vet = (vetor*)malloc(sizeof(vetor));
    printf("Digite o numero do RG do cadastro de indice 0: \n");
    scanf("%d", &vet->v[0].rg);
    fflush(stdin);
    
    printf("Digite o nome do cadastro de indice 0: \n");
    scanf("%[A-Z a-z]", vet->v[0].nome);
    fflush(stdin);
    
    printf("Digite o endereço do cadastro de indice 0: \n");
    scanf("%[A-Z a-z, 0-9]", vet->v[0].endereco);

    
    printf("O numero da lista no cadastro 0 é %d \n", vet->v[0].rg);
    printf("O nome da lista no cadastro 0 é %s \n", vet->v[0].nome);
    printf("O endereco da lista no cadastro 0 é %s \n", vet->v[0].endereco);
    return 0;
}

image.png.582a6ffbbe41b66f46f30b41579157c1.png

Alguém sabe me dizer por que ele só me deixar colocar o rg e imprime direto os 3 prints sem eu ter fornecido o nome e endereço?

image.png

  • Obrigado 1
Postado
  Em 07/11/2022 às 22:57, devair1010 disse:

Qual compilador / IDE você está usando  , pois aqui no Dev C++ embarcadero está funcionando bem , e não pulou o scanf

Expandir  

 

Não é o caso de "pular o scanf()" 😄 seria uma inversão de papéis. Isso não pode acontecer. Seria talvez melhor dizer que "o scanf() pula" e isso acontece pela ideia infeliz e propagada em toda parte de usar fflush() na entrada. Isso não é oficial e não tem sentido. Não está no padrão. fflush() só está definida para fluxos (streams) de SAÍDA.

 

Não há garantia de q

 

#define MAX 1000

typedef struct
{
    char nome[30];
    char endereco[50];
    int  rg;
} cadastro;

typedef struct
{
    cadastro v[MAX];
    int      n;
} vetor;


 

  •  É bem provável que pra testar não precisasse de 1000 itens no cadastro. Que tal uns 10? A área reservada para isso em geral é pequena (stack size) e pode estourar sem nenhuma razão. Visual Studio acho que usa 4K por exemplo. Sim, é claro que pode aumentar. Só não tem propósito: esse é um programa interativo e ninguém vai ter a paciência de digitar mais que uns poucos valores.
  • o que você chamou de cadastro é um item apenas. E o que chamou de vetor é o cadastro. Use nomes mais expressivos
  • E porque não tem o tamanho lá dentro? O limite? Não acha que seria melhor ter DENTRO do cadastro todas as informações de que precisa? É uma fragilidade não ter esse campo lá dentro.
  • Um int para o RG não é boa ideia: não vai operar com esses valores. um char[] deve ser mais prático.
  • entenda que deve usar `unsigned` ou `size_t` em coisas que sabe que não podem ser negativas. Um chato por exemplo na hora de testar seu programa na sala de aula poderia digitar -42 para o RG. Use o compilador a seu favor

Considere algo como
 

#define MAX 10

typedef struct
{
    char nome[30];
    char endereco[50];
    char RG[10];
} Item;

typedef struct
{
    unsigned lim; // limite
    unsigned n; // total agora
    Item     it[MAX];
} Cadastro;

 

E sua vida fica mais simples.

 

Eu tenho uma lista de uns 20 problemas comuns nos programas acadêmicos que tenho visto aqui e em outras partes. Assim posso recortar e colar da minha lista em tópicos como esse sem ter que ficar escrevendo de novo. Seu programa tem um bom número dos problemas comuns, e acho que isso se deve a material didático ruim ou inexistente e instrutores sem experiência. Todos os programas tem os mesmos problemas.

 

Sobre o programa:
    

  • Nunca leia valores do teclado para alimentar seu programa antes dele estar rodando. Só vai te atrasar e não acrescenta absolutamente nada. Use constantes, use funções que retornam a estrutura preenchida. Leia de arquivos: é trivial em C. Ao terminar os  testes aí sim incorpore a leitura. Um programa interativo é chato para testar. Durante o desenvolvimento ninguém quer interagir com o programa. Nunca escreva um programa interativo, mesmo que seja o objetivo final.
  • Use nomes significativos para as variáveis e fuja de coisas como aux, aux1 e aux2. E não use nomes de variáveis enormes porque em uma expressão fica muito difícil de ler.
  • scanf() foi escrita para ler entrada formatada. Não use para ler do teclado, que claramente não é entrada formatada. Só vai dar mais trabalho. Muito mais trabalho.
  • Ao usar scanf() ou alguma função da família, como fscanf() entenda que ela retorna um valor. E teste. É ingênuo deixar o programa seguir sem testar. TESTE sempre. Exemplo: para 5 especificadores --- aquelas coisas com % na frente e que não tem um asterisco nem outro '%' --- como "%d %d %f %f %d" scanf() pode ler de 0 a 5 itens ou dar erro e retornar -1. Então teste o retorno que vai estar entre -1 e 5...
  • especificadores como "%[A-Z a-z, 0-9]" pouco acrescentam para `scanf()`aqui
  • não use fflush() na entrada. Isso só está definido para fluxos de saída. Em alguns compiladores pode até funcionar, mas é um sinal de fez algo errado e não sabe como consumir os dados.
  • Não existe "lixo de teclado": necessidades como de flush() na entrada indicam apenas que não entendeu bem o que está lendo e o que é a entrada via teclado, free form: o usuário pode digitar qualquer coisa e é o seu programa que tem que se virar O teclado tem ao menos 105 teclas de liberdade e o usuário pode digitar qualquer coisa em qualquer ordem.
  • Nunca escreva um programa interativo. Não vai aprender nada. Não vai ganhar nada. Escreva e teste todas as funções. DEPOIS de tudo testado coloque a parte interativa. isso inclui claro o eventual menu.
  • evite ler do teclado a menos que seja o objetivo do problema. Ler de arquivos é muito mais simples, seguro e fácil de reproduzir. Não há razão para ficar parado em frente a tela minutos inventando nomes de campos e coisas assim: o efeito é que vai acabar não testando direito porque é difícil controlar e repetir testes.
  • Não misture entrada de dados ou formatação com a apresentação dos dados ou a lógica do programa, Isso é um desastre para manutenção e desenvolvimento
  •  Um printf() de 6 linhas é muito, mas muito melhor que 6 printf() de 1 linha. E se só vai mostrar o texto puts() é ainda melhor e dezenas de vezes mais rápido que uma série de printf().

De volta ao programa

 

  •  use funções. É muito mais simples.
  • use comentários. Para você ou para os que vem depois de você ler seu código.
  • se aloca memória libere ao final. Por certo vai perder nota por não fazer isso. Isso se seu programa não cancelar sózinho ao final.
  • não use espaços antes de mudar de linha. Qual o sentido?
  • Não mude de linha ao mostrar uma pergunta e esperar por uma resposta. NUNCA se espera isso. O normal é o cursor ficar na mesma linha, logo depois da pergunta.

 


 

  • Curtir 1
  • Obrigado 1
Postado

trocar os fflush(stdin) pot fgetc(sdin) já vai ser algo positivo no seu programa.

 

E entenda que pelo padrão fflush() não está definida para entrada. Pode ser que funcione em algum compilador. Não há garantia. 

 

Então faça o simples e não use na entrada

  • Curtir 1
  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Mostrar mais  

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

Mostrar mais  
×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!