Onde esta o erro... Linguagem C

7 respostas
A

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:

7 Respostas

T

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.

A

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

A

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);
	}
}
A

@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.

A

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

A

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

A

@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’).

Criado 12 de fevereiro de 2022
Ultima resposta 13 de fev. de 2022
Respostas 7
Participantes 3