Onde esta o erro... Linguagem C

Estou cheio de dúvidas, por favor me digam o que tem de errado com esta entrada de dados. Junto com o programa estou mandando os erros que o compilador apontou, veja abaixo:

Obrigado,
Ronaldo

/*
   Programa de manipulação de arquivo
   Ronaldo Rodrigues Godoi
*/

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

struct registro {
	char nome[80];
	int idade;
	double peso;
	double altura;
}
main() {
	
	struct registro pessoa[10];

	printf("Dados para o arquivo: \n");
	for(int i = 0; i < 10; i++) {
		printf("\n Nome: ");
		scanf("%s", &pessoa.nome[i]);
		printf("\n Idade: ");
		scanf("%d", &pessoa.idade[i]]);
		printf("\n Peso: ");
		scanf("%d", &pessoa.peso[i]])
		printf("\n Altura: ");
		scanf("%d", &pessoa.altura[i]])
	}
}

Veja os erros apontados:

Como está estudando C? Está fazendo algum curso ou usando um material de qualidade? Pois parece que você está tropeçando em alguns conceitos simples.

Algo importante, em qualquer linguagem, é aprender a ler as mensagens de erro. Por exemplo:

main must return int. = main deve retornar int

Em C, sua função main deve retornar int, a mensagem é bem clara. Então mude de:

main(){

para

int main(){

E, embora não seja obrigatório, é bom retornar algo do main, colocando um return no final. Algo como:

int main(){
// código já existente
return 0; //zero tipicamente indica "tudo ok"
}

Falta um ponto e vírgula depois da declaração do seu struct. Seu compilador parece apenas emitir um aviso (“perhaps a semicolor is missing…”), mas é algo que pode causar problemas em outros compiladores.

struct registro {
char nome[80];
int idade;
double peso;
double altura;
}; // ponto e virgula adicionado!

Seguindo adiante, seu array é do tipo registro, mas ao ler você está tentando acessar os membros internos do struct (nome, idade e etc), como arrays.

Por fim, para o tipo double, o scanf precisa de um parâmetro %lf em vez de %d, que é para int.

O main ficaria mais ou menos assim:

int main() {

struct registro pessoa[10];

printf("Dados para o arquivo: \n");
for(int i = 0; i < 10; i++) {
	printf("\n Nome: ");
	scanf("%s", &pessoa[i].nome);
	printf("\n Idade: ");
	scanf("%d", &pessoa[i].idade);
	printf("\n Peso: ");
	scanf("%lf", &pessoa[i].peso);
	printf("\n Altura: ");
	scanf("%lf", &pessoa[i].altura);
}
return 0;
}

Não tenho um compilador C no momento, então não pude testar o que fiz. Efetue os ajustes, entenda as diferenças, e se ocorrerem erros, volte aqui com os novos erros.

No seu outro tópico, te foi sugerido usar fgets no lugar de scanf. Não chegou a dar uma olhada?

Abraço.

2 curtidas

Muito obrigado pelas considerações. Eu olhei as outras respostas e em algumas tinha referência ao scanf também. Eu marquei toca, realmente.

Até logo, abraço,
Ronaldo

Fiz as correções que você indicou TerraSkill, mas ele fica pulando entradas como se já tivesse algo no buffer. Qual a sua sugestão? Veja o código abaixo, quase igual ao seu:

/*

Programa de manipulação de arquivo
Ronaldo Rodrigues Godoi

*/

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

struct registro {
	char nome[80];
	int idade;
	double peso;
	double altura;
};
main() {
	
	struct registro pessoa[10];

	printf("Dados para o arquivo: \n");
	for(int i = 0; i < 10; i++) {
		printf("\n Nome: ");
		scanf("%s", &pessoa[i].nome);
		printf("\n Idade: ");
		scanf("%d", &pessoa[i].idade);
		printf("\n Peso: ");
		scanf("%lf", &pessoa[i].peso);
		printf("\n Altura: ");
		scanf("%lf", &pessoa[i].altura);
	}
}

@anyblueangel3 Ola, tudo bem.
A ‘scanf’ é suficiente para maioria dos iniciantes e se tem falha na entrada com certeza está no fluxo de dados. Observe o formado das ‘scanf’, ele sugere uma entrada sequencial assim:

“JOSE 55 67.0 1.85”

  1. Lista de caracteres delimitada por espaço
  2. Número na categoria dos inteiros
  3. Valor na categoria dos flutuantes
  4. Valor // flutuantes

Agora…, um possível erro de fluxo seria o seguinte:

“JOSE MARIA 55 67.0 1.85”

  1. Lista de caracteres
  2. Lista de caracteres [FAIL]
    É especificado a esperar um valor na categoria dos inteiros, entretanto o primeiro caractere (no fluxo de informação) segue uma lista de caracteres “MARIA”! Ela (função) o ignora e retorna FAIL e as seguintes também, pois esperam dígitos para converter em flutuante.
  • Saber o que cada especificador ("%s", “%lf”, “%d”) significa não evitará eventuais falhas na digitação, mas reduz. Logo explique o que deseja, a si mesmo, assim:

Exemplo

#include"stdio.h"
#include"stdlib.h"
#include"string.h"
struct registro {
     char nome[80];
     int  idade;
     double peso;
     double altura;
};
int
main (void) {
  struct registro pessoas[10];
  printf ("Ola! Esse e o cadastro de dados para o arquivo, espero por 10x cadastro. Vamos la: \n\n");
  for (int i = 0; i < 10; i++) {
      printf (" Digite o Nome (uma palavra max. 79 letras) ..........: ");
      scanf ("%s", &pessoas[i].nome[0]);

      printf (" Digita a Idade (numero inteiro somente decimais) ....: ");
      scanf ("%d", &pessoas[i].idade);

      printf (" Digite o Peso (flutuante ex: 80 ou 80.5) ............: ");
      scanf ("%lf", &pessoas[i].peso);

      printf (" Digite a Altura (flutuante ex: 1.8 ou 1.85) .........: ");
      scanf ("%lf", &pessoas[i].altura);

     printf ("\n");
  }
  return 0;
}

Sem título[
[:slight_smile:] Notou cada tipo conforme esperado e sem falhas.

1 curtida

Tudo bem, AnsiC.

Eu consegui fazer uma entrada de dados meia boca usando:

int c;
while ( (c = getchar()) != '\n' && c != EOF ) { }

Agora vou consultar meu livro (um livro gratuito e bem didático em pdf que faz parte da bibliografia de uma pós que estou fazendo) e gravar essas informações. Mas estou com algumas dúvidas. O livro só fala de gravação de inteiros e strings. Minha dúvida é qual comando deve ser usado para gravar todos estes dados em um registro string (nome), int (idade), double (peso), double (altura). Além disso quero fazer a leitura e o processamento dos dados, resultando no índice de massa corpórea.

Fico muito grato pela atenção que o pessoal do GUJ tem me dado. Vou seguindo aqui nas minhas tentativas e se puderem me mandem alguns comandos que posso usar na gravação daquela struct e na leitura.

Um grande abraço,
Ronaldo

Tenho uma boa notícia e uma má. A boa notícia é que fprintf grava certinho os dados a má notícia é que não está gravando o nome com os sobrenomes e eu não sei se isto acontece por causa do fprintf ou é um problema na entrada de dados (scanf("%s",pessoa[i].nome). Veja o programa e o arquivo que está sendo gerado pela linguagem C.

Fiquei feliz porque gravou, agora é só acertar os detalhes.

Seguem o programa e o arquivo (lembrando, todos nomes tinham sobrenome e deveriam ser gravados 80 caracteres). E agora gente o que eu faço para corrigir esses erros?

Atenciosamente,
Ronaldo

/*

   Programa de manipulação de arquivo
   Ronaldo Rodrigues Godoi
   
*/

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

struct registro {
	char nome[80];
	int idade;
	double peso;
	double altura;
};

main() {
	
	struct registro pessoa[10];

	printf("Dados para o arquivo: \n");
	for(int i = 0; i < 4; i++) {
		int c;
		//while ( (c = getchar()) != '\n' && c != EOF ) { }
		printf("\n\n Nome: ");
		scanf("%s", &pessoa[i].nome);
		while ( (c = getchar()) != '\n' && c != EOF ) { }
		printf("\n Idade: ");
		scanf("%d", &pessoa[i].idade);
		while ( (c = getchar()) != '\n' && c != EOF ) { }
		printf("\n Peso: ");
		scanf("%lf", &pessoa[i].peso);
		while ( (c = getchar()) != '\n' && c != EOF ) { }
		printf("\n Altura: ");
		scanf("%lf", &pessoa[i].altura);
	}
	
	FILE *ponteiro;
	ponteiro = fopen("imc.txt", "a");
	if(!ponteiro) {
		printf("\nErro ao abrir arquivo!\n");
		fclose(ponteiro);
		exit(0);
	}
	else
		printf("\nArquivo aberto com sucesso\n");
	for(int i = 0; i < 4; i++) {
		fprintf(ponteiro, "%s", pessoa[i].nome);
		fprintf(ponteiro, "%d", pessoa[i].idade);
		fprintf(ponteiro, "%lf", pessoa[i].peso);
		fprintf(ponteiro, "%lf",pessoa[i].altura);
	}
	fclose(ponteiro);
	return(0);
	
}

Arquivo gerado pelo programa acima:

Ronaldo4882.0000001.700000Adriana4160.0000001.580000Patricia4060.0000001.580000Stavros2175.0000001.750000

@anyblueangel3
Para gravar uma lista de caracteres com espaços o especificador “%s” não serve, eu disse anteriormente que esse especificador captura uma lista delimitada por espaço, ou seja, uma palavra.

Agora sei que nome é nome completo (primeiro e todos os nomes depois dele) e por conta disso mais que 1 palavra! Pergunta-se, como poderia capturar a linha inteira usando a ‘scanf’?

Usando ‘scanset’ " %[^\n]"
Note que esse especificado insinua que o limite de captura é ocorrência ‘\n’.

Exemplo
Escrevo programa que solicita o nome completo dos genitores, para isso usei duas chamadas da ‘scanf’ para capturar cada informação separada por linha (NL).

#include"stdio.h"
int
main (void) {
  char pai_nome_completo[120];
  char mae_nome_completo[120];

  printf ("Cadastro de genitores\n\n");
  printf ("Nome(119 letras)completo do Pai ......: "); scanf (" %[^\n]", &pai_nome_completo[0]);
  printf ("Nome(119 letras)completo da Mae ......: "); scanf (" %[^\n]", &mae_nome_completo[0]);


  printf ("\n\nGENITORES\n");
  printf ("|PAI= %s\n", pai_nome_completo);
  printf ("|MAE= %s\n", mae_nome_completo);
  return 0;
}

Sem título1

Lembrando que cstring precisa de 1 caractere nulo que fica no fim da lista, sendo uma vetor o seu último item tem valor 0.

O formato do arquivo está sem separador. O coerente com a entrada é o separador ser NL (’\n’).