My program is crashing after I changed it. Reading from files [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am doing a project and when I try to use a file to help me keep recording the number of the register of a user.
After I had the part of creating a file, my program start crashing everytime I call a function that I changed (Ler_Pessoa()). It doesnt report any error or warning and I've not been able to understand why it's behaving like that.
I have two files, one is working correctly and I need the secound one to start in 0 everytime I delete the "Data.txt" file.
If you could take a look at my code, I would appreciate.
My header file:
#define ARQ "Dados.txt" /*ARQUIVO COM OS DADOS*/
#define ARQ_REG "Registo.txt" /*Arquivo que vai contabilizando o numero do registo */
FILE *fp;
FILE *reg;
typedef struct
{
char Nome[100];
int Sala;
int Hora_inicio;
int Minuto_inicio;
int Hora_fim;
int Minuto_fim;
long int numero_registo;
char Status; /* '*' Indica que o registo está apagado */
} PESSOA;
void Numero_Registo();
void Listar_Reservas();
void Apagar_Pessoa();
void Alterar_Pessoa();
void Inserir_Pessoa();
void Pesquisar_Nome(char *s);
void Iniciar();
void Ler_Pessoa(PESSOA *p);
void Mostrar_Pessoa(PESSOA p);
void Adicionar_Pessoa(PESSOA p);
void Mensagem(char *msg);
In Numero_Registo.c:
#include "header.h"
void Numero_Registo() /*
* Verifica se o Arquivo REG já existe. Se não existir, o numero de registo começa a 0.
* Se já existir, abre-o em Modo de Leitura e Escrita (r+b)
*/
{
int i = 0;
reg = fopen(ARQ_REG, "r+b"); /* Tenta Abrir*/
if (reg==NULL)
{
reg=fopen(ARQ_REG, "w+b");
fprintf("%d",i) ;/*Cria o Arquivo*/
}
fclose(reg);
}
In Ler_Pessoa.c:
#include "header.h"
void Ler_Pessoa(PESSOA *p) /*Esta função permite ler os dados inseridos por um utilizador de modo a fazer a reserva*/
{
int num_reg;
reg = fopen (ARQ_REG,"r");
fscanf("%d", &num_reg);
num_reg++;
fclose(reg);
reg = fopen(ARQ_REG,"w");
fprintf ("%d", num_reg);
fclose(reg);
printf("Introduza o seu Nome (Primeiro e Ultimo) : "); gets(p->Nome);
printf("Introduza o numero da sala que quer reservar: "); scanf("%d", &p->Sala);
printf("Introduza a partir de que horas quer reservar a sala (HH:MM): "); scanf("%2d:%2d",&p->Hora_inicio , &p->Minuto_inicio);
printf("Introduza ate que horas quer reservar a sala (HH:MM): "); scanf("%2d:%2d", &p->Hora_fim , &p->Minuto_fim);
p -> Status = ' ';
p -> numero_registo = num_reg;
fflush(stdin);
system("cls");
}

In your posted source code, the fscanf() and the fprintf() are called without the file pointer . Changing it to
fscanf( reg, "%d", &num_reg );
and
fprintf( reg, "%d", num_reg );
could be all.

Related

Problem with struct fields in C, pls help :c [duplicate]

This question already has answers here:
How should character arrays be used as strings?
(4 answers)
Closed 3 months ago.
I have a problem with the a struct´s fields.The code compile but doesn´t work as is should, This is how i define my struct.(Srry for the bad english, its my first time in stackoverflow :)
struct registro {
char Pais[3];
char Nombre[20];
char Apellido[20];
char Clase[1];
char Nivel[2];
char Genero[1];
int Edad;
};
i can write on struct without problem. The words in bold are the ones that i typed
=======Agregue los datos del nuevo estudiante=======
Ingrese Pais : **ARG**
Ingrese Nombre del Estudiante : **Gonzalo**
Ingrese Apellido : **Suarez**
Ingrese Clase Social : **A**
Ingrese Nivel de Ingles : **C1**
Ingrese Edad : **20**
Ingrese Genero : **M**
______________________________
ALUMNO AGREGADO DE FORMA EXITOSA! :)
Desea Agregar otro estudiante: S/N
The problem is when i want to se file this happen:
=======Archivos de Estudiantes=======
ARCHIVO :
___________
Pais : ARGGonzalo
Nombre y Apellido : Gonzalo Suarez
Clase : AC1M
edad : 20
Nivel de ingles : C1M
Genero : M
________________________________
i discovered that for some reason the code saves the field Pais,Clase and Nivel wrong, i checked and its not a problem in the printf, i dont know why or how to fix it, I think that theres some library o im using wrong the scanf
heres the code:
#include"stdio.h"
#include"conio.h"
#include"stdlib.h"
void agregar();
void ver_archivo();
void buscar();
void eliminar();
struct registro {
char Pais[3];
char Nombre[20];
char Apellido[20];
char Clase[1];
char Nivel[2];
char Genero[1];
int Edad;
};
void agregar(){
char respuesta2;
FILE *fp;
int n,i;
struct registro reg;
do{
system("cls");
printf("\t\t\t\t=======Agregue los datos del nuevo estudiante=======\n\n\n");
fp=fopen("Datos.dat","w");
printf("\n\t\t\tIngrese Pais : ");
scanf("%s",&reg.Pais);
printf("\n\t\t\tIngrese Nombre del Estudiante : ");
scanf("%s",&reg.Nombre);
printf("\n\t\t\tIngrese Apellido : ");
scanf("%s",&reg.Apellido);
printf("\n\t\t\tIngrese Clase Social : ");
scanf("%s",&reg.Clase);
printf("\n\t\t\tIngrese Nivel de Ingles : ");
scanf("%s",&reg.Nivel);
printf("\n\t\t\tIngrese Edad : ");
scanf("%d",&reg.Edad);
printf("\n\t\t\tIngrese Genero : ");
scanf("%s",&reg.Genero);
printf("\n\t\t\t______________________________\n");
if(fp==NULL){
fprintf(stderr,"ERROR: NO SE PUDO ABRIR EL ARCHIVO");
}else{
printf("\t\t\tALUMNO AGREGADO DE FORMA EXITOSA! :)\n");
}
fwrite(&reg, sizeof(struct registro), 1, fp);
fclose(fp);
printf("\t\t\tDesea Agregar otro estudiante: S/N");
scanf("%s",&respuesta2);
}while(respuesta2=='S');
}
my profesor suggest me to change
fp=fopen("Datos.dat","w");
to
fp=fopen("Datos.dat","wb");
but didnt work
you are putting strings like ARG into a field that is char[3]. Strings in c are zero terminated so you need char[4]. 2 rules for char string in c
always allocate one extra character
make sure that there is a \0 character at the end of the string

Need help manipulating files in C, how can I read more than one line in a function at a time?

sorry for any mistakes, my native language is not english.
I need help with my code:
// Esse programa lê dados de um arquivo TXT, contendo nome, altura e peso
// entao ele retorna esses mesmos dados, alem de informar o IMC da pessoa que esta nos dados
// informando tambem se é obesa ou magra etc.
// Raphael Azambuja Silva Macedo 2020
#include <stdio.h>
#include <stdlib.h>
// Estruturas
typedef struct // Struct das pessoas
{
char nome[100];
int peso;
float altura;
} pessoa;
// Prototipos
float imc(int peso, float altura);
void showIMC(float imcalculado);
void showP(char nome[100], int peso, float altura);
void mIMC(char nome1[100], char nome2[100], int peso1, int peso2, float altura1, float altura2);
pessoa getP(char fns[100]);
// Variaveis externas
const int MAXFN = 50;
int
main()
{
int i=0; // Contador
int n,m; // Valor da struct das pessoas comparadas
char fn[MAXFN]; // Nome do arquivo
float valorimc; // valor do IMC
FILE *file = NULL; // Ponteiro que abre o arquivo
printf("\nDigite o nome do arquivo: ");
scanf("%s", fn);
file = fopen(fn, "r");
if (file == NULL) // Checagem para ver se o arquivo abriu corretamente
{
fprintf(stderr, "ARQUIVO NAO PODE SER ABERTO");
return 0;
}
pessoa z[4]; // Variavel Z da struct pessoa
for (i = 0; i<4 ; i++)
{
z[i] = getP(fn);
valorimc = imc(z[i].peso,z[i].altura); // Chamando a função que calcula o resultado
showP(z[i].nome,z[i].peso,z[i].altura); // Chamando a função que mostra os dados
showIMC(valorimc); // Chamando a função que calcula e mostra o IMC
}
printf("\n=================\n");
printf ("\n\nDigite a enumeracao das pessoas que quer comparar o IMC, sendo a primeira ''0''\n");
scanf(" %d",&n);
scanf(" %d",&m);
mIMC(z[n].nome,z[m].nome,z[n].peso,z[m].peso,z[n].altura, z[i].altura);
fclose(file);
return 0;
}
float // Função que calcula o IMC
imc(int peso, float altura)
{
float resultado;
resultado = peso / (altura*altura);
return resultado;
}
void
showIMC(float imcalculado) // Função que mostra os dados do IMC
{
printf("O IMC dessa pessoa eh: %f" ,imcalculado);
if (imcalculado <= 18.5)
{
printf("\nMagreza");
}
else if (imcalculado > 18.5 && imcalculado <= 24.9)
{
printf("\nPeso normal");
}
else if (imcalculado > 24.9 && imcalculado <= 30)
{
printf("\nSobrepeso");
}
else
{
printf("\nObesidade");
}
}
void
showP(char nome[100], int peso, float altura) // Função que mostra os dados da pessoa
{
printf("\n=================\n");
printf("Nome da pessoa: %s\nPeso da pessoa: %d\nAltura da Pessoa: %f\n",nome,peso,altura);
}
void // Função que compara ambos IMC
mIMC(char nome1[100], char nome2[100], int peso1, int peso2, float altura1, float altura2)
{
int IMC1,IMC2; // IMC de cada Pessoa
IMC1= peso1 / (altura1*altura1);
IMC2= peso2 / (altura2*altura2);
if (IMC1>IMC2)
{
printf("\n=====================\n");
printf("A pessoa %s tem o menor IMC." ,nome2);
}
else if (IMC2>IMC1)
{
printf("\n=====================\n");
printf("A pessoa %s tem o menor IMC." ,nome1);
}
else
{
printf("\n=====================\n");
printf("As duas pessoas tem o mesmo IMC.");
}
}
pessoa getP(char fns[100])
{
pessoa t;
FILE *file = fopen(fns, "r");
fscanf (file, " %[^0123456789] %d %f" ,t.nome,&t.peso,&t.altura);
return t;
}
What I need to do is:
Every time I call the ''getP'' function I need to read a diferent line of info from the txt file, however, every time the function is called it starts reading from the beginning, so I always get the first line.
The txt file is:
beltano das couves 90 1.7
fulano de tal 80 1.7
sicrano de tel 75 1.7
deltrano de tol 70 1.7

Is there an error while writing the R record in the file " in function "ResultatdeMouvement"?

The Exercise is about filling Products names with their Stock capacity in file named fichierProduit and filling the movement (Import and Export) of this products in file named fichierMouvment. After filling these 2 files I create another file fichierdeResultat so I can write in it the new Stock Capacity. After doing some math the function related to this is ResultatdeMouvement, when displaying the Result it only displays the first product.
I tried to copy the name into the record "Resultat" (R) and then write it into the fichierdeResultat while displaying them in the function AfficheDeProduitApresMouvement it seems displaying only the first product name in file fichierProduit.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct Produit{
char NomP[10] ;
int StockP;
};
struct Mouvement{
char MouveP[10];
int MouveAp;
int MouveV;
};
struct Resultat{
char NomPr[10];
int StockR;
};
//INSERTING NEW PRODUCTS LIST
void SaisirProduits(FILE* ficheierProduit){
struct Produit P;
ficheierProduit = fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","wb");
char rep;
do {
fseek(ficheierProduit, 0, SEEK_END);
printf("Saisir Nom de Produit: ");
scanf("%9s",&P.NomP);
printf("Saisir Capacite de Stock de Produit: ");
scanf("%i",&P.StockP);
fwrite (&P, sizeof(struct Produit), 1,ficheierProduit);
if(fwrite!=0){
printf("\n\Produit Ajoute avec succees !\n\n");
}
printf("Voulez Vouz Saisir un autre Produit (O,N): ");
scanf(" %c",&rep);
}while(toupper(rep)!='N');
fclose(ficheierProduit);
}
//INSERTING NEW MOVEMENT LIST
void SaisirMouvement(FILE* fichierMouvment){
struct Mouvement M;
fichierMouvment = fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FMouvment.dat","wb");
char rep;
do {
fseek(fichierMouvment, 0, SEEK_END);
printf("Saisir Nom de Produit a Ajouter un mouvement: ");
scanf("%9s",&M.MouveP);
printf("Saisir Capacite d'approvisionnement: ");
scanf("%i",&M.MouveAp);
printf("Saisir Nombre Vendu de ce Produit: ");
scanf("%i",&M.MouveV);
fwrite (&M, sizeof(struct Mouvement), 1,fichierMouvment);
if(fwrite!=0){
printf("\n\Mouvement Ajoute avec succees !\n\n");
}
printf("Voulez Vouz Saisir un autre Mouvement (O,N): ");
scanf(" %c",&rep);
}while(toupper(rep)!='N');
fclose(fichierMouvment);
}
//Function to verify if the Products Exist or not
int VerifierProduitExistouNon(char NomdeProduit[10],FILE* ficheierProduit){
struct Produit P; ficheierProduit=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","r+");
int found=0;
while(!feof(ficheierProduit)){
fread(&P,sizeof(P),1,ficheierProduit);
if(strcmp(P.NomP,NomdeProduit)==0){
found=1;
return found;
}else if(feof(ficheierProduit) && found==0)
return found;
}
fclose(ficheierProduit);
}
//Add New Products to the File
void AjouterNouveauProduit(FILE* fichierProduit){
struct Produit P;
fichierProduit=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","ab+");
printf("Saisir Nom de Nouveau Produit: ");
scanf("%9s",&P.NomP);
if(VerifierProduitExistouNon(P.NomP,fichierProduit)!=0)
printf("\n\nProduit deja Exist Merci de Verifier !\n\n");
else{
printf("\nSaisir Capcite de Stock de Produit: ");
scanf("%i",&P.StockP);
fwrite (&P, sizeof(struct Produit), 1,fichierProduit);
printf("\nSaisir de nouveau Produit avec Success ! \n");
}
fclose(fichierProduit);
}
//INSERTING NEW MOUVEMENT
void AjouterNouveauMouvement(FILE* fichierMouvment,FILE* fichierProduit){
struct Mouvement M;
fichierMouvment = fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FMouvment.dat","ab+");
printf("Saisir Nom de Produit a Verifier S'il exist: ");
scanf("%9s",&M.MouveP);
if(VerifierProduitExistouNon(M.MouveP,fichierProduit)!=0){
printf("\n\nProduit Exist Ajout de Nouveau Mouvement.....\n\n");
printf("\nSaisir Capcite d'approvisionnement de Ce Produit: ");
scanf("%i",&M.MouveAp);
printf("\nSaisir Capcite de Vente de Ce Produit: ");
scanf("%i",&M.MouveV);
fwrite (&M, sizeof(struct Mouvement), 1,fichierMouvment);
if(fwrite!=0){
printf("\nSaisir de nouveau Produit avec Success ! \n");
}
}else{
printf("\n\nCe Produit N existe pas dans le Stock Merci de Verifier ! \n\n");
}
fclose(fichierMouvment);
}
//TRYING TO FILE THE RESULT FILE
void ResultatdeMouvement(FILE* ficheierProduit,FILE* fichierMouvment,FILE* fichierResultat){
struct Produit P;
struct Mouvement M;
struct Resultat R; ficheierProduit=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","r+");
fichierMouvment=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FMouvment.dat","r+");
fichierResultat=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FResultat.dat","wb");
while(!feof(ficheierProduit)){
fread(&P,sizeof(P),1,ficheierProduit);
while(!feof(fichierMouvment)){
fread(&M,sizeof(M),1,fichierMouvment);
if(strcmp(P.NomP,M.MouveP)==0){
strcpy(R.NomPr,P.NomP);
R.StockR=P.StockP+(M.MouveAp-M.MouveV);
}
}
fwrite(&R,sizeof(R),1,fichierResultat);
}
fclose(ficheierProduit);
fclose(fichierMouvment);
fclose(fichierResultat);
}
void AfficheDeMouvement(FILE* fichierdeMouvement){
struct Mouvement M;
fichierdeMouvement=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FMouvment.dat","r+");
while(fread(&M,sizeof(M),1,fichierdeMouvement)){
printf("\n\nNom de Produit: %s | approvisionnement= %i | Vente= %i\n\n ",M.MouveP,M.MouveAp,M.MouveV);
}
fclose(fichierdeMouvement);
}
void AfficheDeProduitavantMouvement(FILE* fichierProduit){
struct Produit P;
fichierProduit=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","r+");
while(fread(&P,sizeof(P),1,fichierProduit)){
printf("\n\nNom de Produit: %s | Stock Valable = %i \n\n",P.NomP,P.StockP);
}
fclose(fichierProduit);
}
void AfficheDeProduitApresMouvement(FILE* fichierResultat){
struct Resultat R;
fichierResultat=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FResultat.dat","r+");
while(fread(&R,sizeof(R),1,fichierResultat)){
printf("\n\nNom de Produit: %s | Stock Valable Apres Mouvement: %i \n",R.NomPr,R.StockR);
}
fclose(fichierResultat);
}
//Main
int main()
{ FILE* Produit;//file of the products
FILE* MouvementdeProduit;//file of the mouvment
FILE* ResultatdeMouvedeProduit;//file of the result
AfficheDeProduitavantMouvement(Produit);
AfficheDeMouvement(MouvementdeProduit); ResultatdeMouvement(Produit,MouvementdeProduit,ResultatdeMouvedeProduit);
AfficheDeProduitApresMouvement(ResultatdeMouvedeProduit);
}
There are many problems with your code, some of which I addressed in the comments. I will/did not identify all problems. I will just point you to the problem you are asking about.
The problem is that you skip a lot of records in the input file, so before processing the next product you must rewind the input file:
while(fread(&P,sizeof(P),1,ficheierProduit))
{
// You now have a product.
// Now collect its stock.
R.StockR= 0;
*R.NomPr= '\0';
while(fread(&M,sizeof(M),1,fichierMouvment))
{
if(strcmp(P.NomP,M.MouveP)==0){
strcpy(R.NomPr,P.NomP);
R.StockR=P.StockP+(M.MouveAp-M.MouveV);
}
}
if (*R.NomPr!='\0') fwrite(&R,sizeof(R),1,fichierResultat);
// You have now possibly skipped lots of products.
// So you must rewind the file.
fseek(fichierMouvment,0, SEEK_SET);
}

Can't use struct pointers as parameters of mutiple functions

This is a program to register books in a library with title, writer and price.As well as calculate things such as averages, highest price book... It ran pretty well when i used a vector {struct livro Livros[1000]} instead of a pointer {struct livro *Livros}.
I used the pointers to dynamically allocate memory for the book list and everything runs fine registering the books. but when i try to calculate the average, which calls another function to main, the program crashes and the compiler(i use visual studio in my school) shows that message:
Unhandled exception at 0x00ec174c in Livraria.exe: 0xC0000005: Access violation reading location 0xcccccd94.
I tried to use the function to locate by writer instead of the average and it crashed just after i have put the string. Certainly when it used the "Livros[i].autor" to compare the strings
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define flush_toilet (fflush(stdin))
//mude o #define dependendo do seu SO
//__fpurge(stdin); "linux"
//fflush(stdin); "windows"
struct livro {
char titulo [100];
char autor [100];
float prec;
};
//register
void cadastro (int *qtd, struct livro *Livros){
int i;
Livros=NULL;
printf("Insira a quantidade de livros:");//defines the quantity(variable "qtd") of books which will pass to the main function(it worked when i used vectors)
scanf ("%i",qtd);
flush_toilet;
Livros = malloc( *qtd *sizeof(struct livro)); //allocates the memory for the list
printf ("insira os dados de cada livro:");
for (i=0;i<*qtd;i=i+1){
printf ("\n\n\ninsira o titulo:");
gets (Livros[i].titulo); //title
flush_toilet;
printf ("\ninsira o nome:");
gets (Livros[i].autor); //writer
flush_toilet;
printf ("\ninsira o preco :");
scanf ("%f",&Livros[i].prec);//price
flush_toilet;
}
}
//calculate average of prices
float media (int qtd, struct livro *Livros){
int i;
float media=0;
for (i=0;i<qtd;i=i+1){
media=media+Livros[i].prec;
}
media=media/qtd;
return media;
}
//calculate number of books above average
int qtd_acima_med (float media, struct livro *Livros, int qtd){
int acima=0,i;
for (i=0;i<qtd;i=i+1){
if(Livros[i].prec>media){
acima=acima+1;
}
}
return acima;
}
//locate a book by writer
void localizar(int qtd, struct livro *Livros){
int i;
char autor[100];
printf("\ndigite o nome do autor cujos livros deseja encontrar:\n");
gets (autor);
flush_toilet;
printf("\n");
for (i=0;i<qtd;i=i+1){
if((strcmp (autor, Livros[i].autor))==0){
puts(Livros[i].titulo);
printf("\n");
}
}
}
//finds and displays the most expensive book
void mais_caro (int qtd, struct livro *Livros ){
int i, ncaro;
float caro=0;
for (i=0;i<qtd;i=i+1){
if (Livros [i].prec>caro){
caro=Livros [i].prec;
ncaro=i;
}
}
puts (Livros[ncaro].titulo);
printf ("preco: %f\n", Livros[ncaro].prec);
}
void main (){
struct livro *Livros;
int qtd=-1, selec=1, nacima=-1;
float med=-1;
while (selec!=0){
printf ("\n\n\nDigite 0 para sair,\n 1 para cadastrar,\n 2 para calcular a media,\n 3 para calcular os livros acima da media,\n 4 para localizar o livro pelo autor,\n 5 para achar o mais caro.\n\n");
scanf("%i", &selec);
flush_toilet;
switch (selec){
case 0:
break;
case 1:{
cadastro(&qtd, Livros);
break;
}
case 2:{
if(qtd<0){
printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
break;
}
med=media(qtd, Livros);
printf("A media e igual a: %f \n", med);
break;
}
case 3:{
if(med<0){
printf("erro a media n foi calculada\n");
break;
}
nacima = qtd_acima_med (med, Livros, qtd);
printf("A qtd de livros com preco acima da media e: %i \n", nacima);
break;
}
case 4:{
if(qtd<0){
printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
break;
}
localizar(qtd, Livros);
break;
}
case 5:{
if(qtd<0){
printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
break;
}
mais_caro (qtd, Livros);
break;
}
}
}
free(Livros);
}
When I compile, I get the following error:
1>main.c(138) : warning C4700: uninitialized local variable 'Livros' used
This looks to be the cause of the bug. To fix, you need to return the allocated array from cadastro:
struct livro * cadastro (int *qtd){
int i;
struct livro *Livros =NULL;
printf("Insira a quantidade de livros:");//defines the quantity(variable "qtd") of books which will pass to the main function(it worked when i used vectors)
scanf ("%i",qtd);
flush_toilet;
Livros = malloc( *qtd * sizeof(struct livro)); //allocates the memory for the list
printf ("insira os dados de cada livro:");
for (i=0;i<*qtd;i=i+1){
printf ("\n\n\ninsira o titulo:");
gets (Livros[i].titulo); //title
flush_toilet;
printf ("\ninsira o nome:");
gets (Livros[i].autor); //writer
flush_toilet;
printf ("\ninsira o preco :");
scanf ("%f",&Livros[i].prec);//price
flush_toilet;
}
return Livros;
}
And then later use the return in main ():
void main (){
struct livro *Livros = NULL;
int qtd=-1, selec=1, nacima=-1;
float med=-1;
while (selec!=0){
// Snip
switch (selec){
// snip
case 1:
{
if (Livros != NULL)
{
free(Livros);
Livros = NULL;
}
Livros = cadastro(&qtd);
}
break;
You also need to check the return values of scanf() and gets() in case there is no more input or invalid input, and have a default case in the event the user enters an invalid value for selec. You should also consider replacing gets() with fgets() to prevent buffer overruns. But the immediate cause of the crash is the uninitialized variable. Presumably your compiler also reports a similar warning, and if it does, warnings like this should always be fixed.

Why the last iteration repeats?

My question refers to the while(!feof(arch)) that repeats the last registry two times. Thanks if you take some of your time to answer. I'm in first year learning basics.
The information is on an archive, so the first input shouldn't be 's' because it isn't the first time to input. Then the program list the infomation but the last registry repeats two times.
#include <stdio.h>
typedef struct{
int legajo;
char nombre[30];
int ingreso;
int pparcial;
int sparcial;
} reg_alumno;
reg_alumno funcionleer(void);
typedef FILE * archivo; //Se define el tipo de dato "archivo".
archivo arch; //Se declara una variable de archivo.
int main(void){
reg_alumno alumno,alu;
int ca,i,j=0;
char respuesta;
printf("Desea ingresar datos por primera vez?");
scanf("%c",&respuesta);
printf("Ingrese cantidad alumnos");
scanf("%d",&ca); //Pide cantidad alumnos
if(respuesta=='s'){
arch = fopen("alumnos.dat","w"); //Crear archivo para escribir, crea si no existe)
for(i=0;i<ca;i++){
alumno = funcionleer(); //Lee alumno
fseek(arch,sizeof(reg_alumno)*i,SEEK_SET); //Busca la última posición del archivo
fwrite(&alumno,sizeof(reg_alumno),1,arch); //Escribe en la última posición
}
}
else{
arch = fopen("alumnos.dat","r+");
while(!feof(arch)){
fseek(arch,sizeof(reg_alumno)*j,SEEK_SET); //Pasa de registro en registro(alumno en alumno).
fread(&alu,sizeof(reg_alumno),1,arch); //Trae a la memoria principal un alumno
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
}
fclose(arch); //Cierra el archivo
}
reg_alumno funcionleer(void){ //Función leer
reg_alumno alumno;
printf("Ingrese el numero de legajo:\n");
scanf("%d",&alumno.legajo);
printf("Ingrese el nombre:\n");
scanf("%s",alumno.nombre);
return(alumno);
}
Good to check result of IO operations #WhozCraig.
The code's problem is that its prints even if fread() fails.
// No check of return value.
fread(&alu,sizeof(reg_alumno),1,arch);
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
Code uses feof() incorrectly. Many SO posts on that.
Since OP implies code is required to use feof() by teacher: following are 2 good ways to use feof()
for (;;) {
if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
if (fread(&alu,sizeof(reg_alumno),1,arch) == 0) break;
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
// If loop quit because of EOF
if (feof(arch)) printf("Success");
else if (!ferror(arch)) printf("IO Error");
Or
for (;;) {
if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
fread(&alu,sizeof(reg_alumno),1,arch);
if (!feof(arch)) break;
if (!ferror(arch)) break;
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}

Resources