I can't get fread to work with a struct array - c

I'm trying to print the contents of a binary file, but when I run the code, after inserting the various variables, they don't get printed, and the algorithm just ends. I think the fwrite is correct, but I'm not sure.
This is the code:
typedef struct{
char descrizione[80];
float voto;
}materia;
typedef struct{
char nome[80];
char cognome[80];
materia b[2];
}studente;
void lettura(FILE *fp, int n, studente a[n])
{
int i, j;
fp=fopen("file.bin","wb");
for(i=1;i<=n;i++)
{
printf("\nInserisci il nome del %d studente: ",i);
gets(a[i].nome);
printf("Inserisci il cognome del %d studente: ",i);
gets(a[i].cognome);
for(j=1;j<=2;j++)
{
printf("Inserisci la materia %d: ",j);
gets(a[i].b[j].descrizione);
printf("Inserisci il voto di %s %s in %s: ",a[i].nome,a[i].cognome,a[i].b[j].descrizione);
scanf("%f",&a[i].b[j].voto);
getchar();
}
fwrite(&a[i],sizeof(studente),1,fp);
}
fclose(fp);
}
int main(int argc, char *argv[]) {
int n=2, i=1;
studente a[n];
FILE *fp;
fp=fopen("file.bin","wb");
fclose(fp);
lettura(fp,n,a);
while(fread(&a[0],sizeof(studente),1,fp)>0)
{
printf("%s, %s, %s, %f",a[1].nome,a[i].cognome,a[i].b[i].descrizione,a[i].b[i].voto);
i++;
}
return 0;
}

Related

Scan (read) from BIN file

I need to solve a problem. I need to create two functions which scan user's input information and put in into structure array and then put all array to BIN file (with function fwrite()) and other function - read from BIN file with function fread(). You can see my code below. Problem is that I can write to file, but when I read I get filler array element and other element which are empty. How to get only filled struct array element?
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
typedef struct
{
char Lesson[50];
char TeachersName[50];
char TeachersLastName[50];
int Credits;
int NumberOfStudents;
} School;
void ToFile (char *fileName);
void FromFile (char *FileName);
int main()
{
char *fileName[]={"student.bin"};
ToFile (*fileName);
FromFile (*fileName);
return 0;
}
void ToFile (char *fileName)
{
int n, chars;
FILE *fp;
fp = fopen(fileName, "wb");
School Info[20];
if(fp == NULL)
{
printf("Error opening file\n");
exit(1);
}
printf("Testing fwrite() function: \n\n");
printf("Enter the number of records you want to enter: ");
scanf("%d", &n);
for(int i = 0;i<n;i++)
{
printf("\nEnter details of employee %d \n", i + 1);
fflush(stdin);
printf("Lesson: ");
gets(Info[i].Lesson);
printf("Teachers name: ");
gets(Info[i].TeachersName);
printf("Teachers last name: ");
gets(Info[i].TeachersLastName);
printf("Credits: ");
scanf("%d", &Info[i].Credits);
printf("Number of studens: ");
scanf("%d", &Info[i].NumberOfStudents);
chars = fwrite(&Info[i], sizeof(Info), 1, fp);
printf("Number of items written to the file: %d\n", chars);
}
fclose(fp);
}
void FromFile (char *FileName)
{
School Info[20]= { { "", "","",0,0 } };;
FILE * fpp;
fpp = fopen(FileName, "rb");
fread(&Info, sizeof(Info), 1, fpp);
/*
for(int j=0; j<20; ++j) {
printf("\nLesson: %s", Info[j].Lesson);
printf("\nTeachers name: %s", Info[j].TeachersName);
printf("\nTeachers last name: %s", Info[j].TeachersLastName);
printf("\nCredits: %d", Info[j].Credits);
printf("\nNumber of students: %d", Info[j].NumberOfStudents);
printf("\n");
}*/
int j=0;
while (fread(&Info, sizeof(Info), 1, fpp))
{
printf("\nLesson: %s", Info[j].Lesson);
printf("\nTeachers name: %s", Info[j].TeachersName);
printf("\nTeachers last name: %s", Info[j].TeachersLastName);
printf("\nCredits: %d", Info[j].Credits);
printf("\nNumber of students: %d", Info[j].NumberOfStudents);
printf("\n");
j++;
}
fclose(fpp);
}

C program stops after traing to access string array

i'm making a program in C that let the user insert the number of names that he wants, this names is stored in a global array and then they are printed, but the program finishes before, specifically when i try to access to the global array to print the names to show them to the user. I need to have my global array as follows: char *array[10]. This problem just happens when i use the previus syntax, but when i use: char array[10][], all runs fine, what's the problem here? somebody can help me please, i have tried so many hours.
CODE:
#include <stdio.h>
#define MAX 10
int counter = 0;
char *concts[MAX];
void add_2(char *name){
printf("Se anadira un elemento en el index %d\n", counter);
concts[counter] = name;
counter++;
}
void main(){
char *name;
int ingresando = 1, i;
do{
printf("ingresa un nombre: ");
scanf("%s", &name);
add_2(name);
printf("Seguir ingresando? ");
scanf("%d", &ingresando);
}while(ingresando == 1);
printf("Terminado. contador: %d\n", counter);
for(i = 0; i < counter; i++){
char *otherName = concts[i];
printf("%s\n", otherName);
}
}
PROBLEM:
I don't really know, but the program ends before what is expected, it compiles well and does not prompt errors.
EDIT:
The program stops after print "Terminado. contador: %d\n"
Here I made some changes
#include <stdio.h>
#include <string.h>
#define MAX 10
int counter = 0;
char concts[MAX][20];
void add_2(char *name){
printf("Se anadira un elemento en el index %d\n", counter);
strcpy(concts[counter], name);
counter++;
}
int main(){
char name[20];
int ingresando = 1, i;
do{
printf("ingresa un nombre: ");
scanf("%s", name);
add_2(name);
printf("Seguir ingresando? ");
scanf("%d", &ingresando);
}while(ingresando == 1);
printf("Terminado. contador: %d\n", counter);
for(i = 0; i < counter; i++){
char *name = concts[i];
printf("%s\n", name);
}
return 0;
}
Now run it.
#include <stdio.h>
#include <string.h>
void add_2(char *name); //defining prototype of function
#define MAX 10
int counter = 0;
char concts[MAX][20];
void add_2(char *name){
printf("Se anadira un elemento en el index %d\n", counter);
strcpy(concts[counter], name);
counter++;
}
main(){
char name[20];
int ingresando = 1, i;
do{printf("ingresa un nombre: ");
scanf("%s", &name);
add_2(name);
printf("Seguir ingresando? ");
scanf("%d", &ingresando);
}while(ingresando == 1);
printf("Terminado. contador: %d\n", counter);
for(i = 0; i < counter; i++){
char *name = concts[i];
printf("%s\n", name);
}
}
The above answers seem right but the other way is using malloc.
first you must include <stdlib.h> and then edit line 12(char *name) like this
char *name=malloc(21);
*for old version of gcc you must cast the output of malloc to char *

How to use Binary Search on array of string

I have to write a program only using things that i've learned in class, where I register information from a car, sort it and use the Binary Search to search for a cars' license plate. If the license plate is found, print all the info about that especific car, If don't pritnt "Not found" and returns -1. All works fine until the Binary Search, the problem is that it won't find the license plate, It always returns -1.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CARRO 5 // DEFINE TAMANHO DA STRUCT
typedef struct // STRUCT
{
char placa[50];
char marca[50];
char modelo[50];
char ano[50];
char valordiaria[50];
} carro;
carro car[MAX_CARRO];
int compare (const void * a, const void * b)
{
carro *carroA = (carro *)a;
carro *carroB = (carro *)b;
return strcmp(carroA, carroB);
}
int main()
{
int x=0; //COUNTER
for(x=0; x<MAX_CARRO; x++) // CAR REGISTER
{
printf("\nCarro: %d", (x+1));
printf("\nPlaca: ");
scanf("%s",car[x].placa);
printf("Marca: ");
scanf("%s",car[x].marca);
printf("Modelo: ");
scanf("%s",car[x].modelo);
printf("Ano: ");
scanf("%s",car[x].ano);
printf("Valor da diaria: ");
scanf("%s",car[x].valordiaria);
}
qsort (car, MAX_CARRO, sizeof(carro), compare); // USO DO QSORT
printf("\n\nSTRUCT ORDENADA: \n");
for(x=0; x<MAX_CARRO; x++) // MOSTRA NA TELA A STRUCT ORDENADA
{
printf("\n\n\nCarro: %d", (x+1));
printf("\nPlaca: %s", car[x].placa);
printf("\nMarca: %s", car[x].marca);
printf("\nModelo: %s", car[x].modelo);
printf("\nAno: %s", car[x].ano);
printf("\nValor da diaria: %s", car[x].valordiaria);
}
char k[10];
// *****BINARY SEARCH******
printf("\n\n\n*****BUSCA DE PLACAS*****\n\n\n\n");
printf("Digite a placa que deseja procurar: \n");
scanf("%s", &k);
// ***PROBLEM***
int low, high, mid;
low=0;
high = MAX_CARRO-1;
while(low<=high)
{
mid = (low+high)/2;
if (strcmp(k, car[mid].placa)<0)
high=mid-1;
else if (strcmp(k, car[mid].placa)>0)
low=mid+1;
else
{
printf("\nPlaca: %s", car[mid].placa);
printf("\nMarca: %s", car[mid].marca);
printf("\nModelo: %s", car[mid].modelo);
printf("\nAno: %s", car[mid].ano);
printf("\nValor da diaria: %s", car[mid].valordiaria);
}
printf("\n\n****Not found****\n\n\n");
return -1; //
}
}
You have few bugs.
First one is in your compare() function. You can not write this line
return strcmp(carroA, carroB);
Because strcmp is working just with char* types, and carroA and carroB are of type carro*. You should place
return strcmp(carroA->placo, carroB->placo);
Now you will sort your structures by the value of placo.
Now lets take a look at your main function.
First bug in main() is in your line of code
scanf("%s", &k);
You don't need &, you should make it like this
scanf("%s",k);
Second bug is in your while() loop in the last line
return -1;
This is a huge thing because main() will return -1. If you want main() to exit like an error occurred you should write return 1;
Maybe you should use one variable to determine weather you have found what you was looking for in your binary search
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CARRO 5 // DEFINE TAMANHO DA STRUCT
typedef struct // STRUCT
{
char placa[50];
char marca[50];
char modelo[50];
char ano[50];
char valordiaria[50];
} carro;
carro car[MAX_CARRO];
int compare (const void * a, const void * b)
{
carro *carroA = (carro *)a;
carro *carroB = (carro *)b;
return strcmp(carroA->placa, carroB->placa);
}
int main()
{
int x=0; //COUNTER
for(x=0; x<MAX_CARRO; x++) // CAR REGISTER
{
printf("\nCarro: %d", (x+1));
printf("\nPlaca: ");
scanf("%s",car[x].placa);
printf("Marca: ");
scanf("%s",car[x].marca);
printf("Modelo: ");
scanf("%s",car[x].modelo);
printf("Ano: ");
scanf("%s",car[x].ano);
printf("Valor da diaria: ");
scanf("%s",car[x].valordiaria);
}
qsort (car, MAX_CARRO, sizeof(carro), compare); // USO DO QSORT
printf("\n\nSTRUCT ORDENADA: \n");
for(x=0; x<MAX_CARRO; x++) // MOSTRA NA TELA A STRUCT ORDENADA
{
printf("\n\n\nCarro: %d", (x+1));
printf("\nPlaca: %s", car[x].placa);
printf("\nMarca: %s", car[x].marca);
printf("\nModelo: %s", car[x].modelo);
printf("\nAno: %s", car[x].ano);
printf("\nValor da diaria: %s", car[x].valordiaria);
}
char k[10];
// *****BINARY SEARCH******
printf("\n\n\n*****BUSCA DE PLACAS*****\n\n\n\n");
printf("Digite a placa que deseja procurar: \n");
scanf("%s", k);
// ***PROBLEM***
int low, high, mid;
low=0;
high = MAX_CARRO-1;
int found=0;
while(low<=high && !found)
{
mid = (low+high)/2;
if (strcmp(k, car[mid].placa)<0)
high=mid-1;
else if (strcmp(k, car[mid].placa)>0)
low=mid+1;
else
{
found = 1;
printf("\nPlaca: %s", car[mid].placa);
printf("\nMarca: %s", car[mid].marca);
printf("\nModelo: %s", car[mid].modelo);
printf("\nAno: %s", car[mid].ano);
printf("\nValor da diaria: %s", car[mid].valordiaria);
}
}
if(!found)
printf("\n\n****Not found****\n\n\n");
return 0; //
}

trouble reading data from binary file into struct array

I have a binary file with some data I inputted using an array of struct.
However, when I try to read back my values and display them, only the first one prints followed by garbage values.
Where did I go wrong?
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct eagleEmployees{
char userName[16];
char psswd[16];
};
int main()
{
int i;
struct eagleEmployees data[3];
FILE* fptr;
fptr = fopen("eEmployees.bin", "wb");
for(i=0; i<3; i++){
printf("\nEnter client name %d: ", i+1);
scanf(" %s", data[i].userName);
printf("\nEnter client password %d: ", i+1);
scanf(" %s", data[i].psswd);
}
i++;
fwrite(data, sizeof(struct eagleEmployees), 3, fptr);
fclose(fptr);
// I close the file above and reopen for reading below.
FILE *f;
f = fopen("eEmployees.bin", "rb");
for(i=0; i<3; i++){
fread(data,1,sizeof(struct eagleEmployees), f);
printf("\n %s \t %s",data[i].userName, data[i].psswd);
}
fclose(f);
return 0;
}

Bug fix for Dog Database

I am working on a dog database and have one bug I cannot figure out.
The bug is: Thread 1: signal SIGABRT.
Every time I try to search or change for a dog, I get this error code.
My code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SZ_NAME 32
#define SZ_BREED 32
#define SZ_COLOR 16
#define SZ_SEX 8
struct dog_entry
{
char name [SZ_NAME];
char breed [SZ_BREED];
char color [SZ_COLOR];
float weight;
int age;
char sex [SZ_SEX];
};
#define REC_SIZE sizeof(struct dog_entry)
struct dog_entry record[REC_SIZE];
char pr_menu(void);
void addRecord(struct dog_entry *reg, int type);
void modifyRecord(int);
void delete_dog(int g, struct dog_entry *rec);
void view_dog(int, struct dog_entry *reg);
int find_dog(int, struct dog_entry *rec);
void searchRecord(int, struct dog_entry *rec);
int main()
{
struct dog_entry reg;
int i = 0, n;
while(free)
{
char ch = pr_menu();
switch(ch)
{
case '1':
addRecord(&reg, 1);
i++;
break;
case '2':
addRecord(&reg, 2);
break;
case '3': delete_dog(1, &reg);
break;
case '4': view_dog(1, &reg);
break;
case '5': searchRecord(n, &reg);
break;
default: break;
}
if (ch == '6') // exit
break;
}
// system("pause");
}
char pr_menu(void)
{
char ch;
// system("cls");
printf("\n Menu:\n 1.Add\n 2.Change\n 3.Delete\n 4.View\n 5.Search\n 6.Exit\n \nEnter Choice: ");
scanf("%c", &ch);
return ch;
}
//Function that adds a record
void addRecord(struct dog_entry *rec, int type)
{
FILE * f;//define donde se guarda el archivo
f = fopen("database_dog.txt", "w+");//definition of file
// system("cls");
printf("Add the Dog: ");
printf("\n Enter Name: ");
scanf("%s", rec->name);
printf("\n Enter Breed: ");
scanf("%s", rec->breed);
printf("\n Enter Color: ");
scanf("%s", rec->color);
printf("\n Enter Weight: ");
scanf("%f", &rec->weight);
printf("\n Enter Age: ");
scanf("%d", &rec->age);
printf("\n Enter Sex: ");
scanf("%s", rec->sex);
fseek(f, 0, SEEK_END);
fwrite(&rec, sizeof(struct dog_entry), 1, f);//save the data
fclose(f);//close the file
printf("\n\n");
// system("pause");
}
//Function that modifies the record
void modifyRecord(int index)
{
}
//Function that displays records
void view_dog(int total, struct dog_entry *rec)
{
FILE * f;//define donde se guarda el archivo
f = fopen("database_dog.txt", "r+");//definition of file
char name [SZ_NAME];
// system("cls");
printf("View the Dog: ");
printf("\n Enter Dog's Name: ");
scanf("%s", name);
rewind(f);
while(fread(&rec, sizeof(struct dog_entry), 1, f))
{ //apertura del while
if(strcmp(name, rec->name) == 0)//compara una cadena de caracteres
{
printf("\n Name: %s", rec->name);
printf("\n Breed: %s", rec->breed);
printf("\n Color: %s", rec->color);
printf("\n Weight: %f", rec->weight);
printf("\n Age: %d", rec->age);
printf("\n Sex: %s", rec->sex);
printf("\n\n");
// system("pause");
break;
}
}
fclose(f);//close the file
}
int find_dog(int g, struct dog_entry *rec){
FILE * f;//define donde se guarda el archivo
f = fopen("database_dog.txt", "r+");//definition of file
char name [SZ_NAME];
printf("\n Enter Dog's Name: ");
scanf("%s", name);
rewind(f);
int c;
while(fread(&rec, sizeof(struct dog_entry), 1, f))
{ //apertura del while
if(strcmp(name, rec->name) == 0)//compara una cadena de caracteres
{
c++;
break;
}
}
fclose(f);//close the file
return c;
}
void delete_dog(int g, struct dog_entry *rec){
FILE * f;//define donde se guarda el archivo
f = fopen("database_dog.txt", "r+");//definition of file
char name [SZ_NAME];
int num = 0;
// system("cls");
printf("Delete Record: ");
printf("\n Enter Dog's number: ");
scanf("%d", &num);
fseek(f, num * sizeof(struct dog_entry), SEEK_SET);
fread(&rec, sizeof(struct dog_entry), 1, f);
fclose(f);//close the file
}
//Function that searches for the record
void searchRecord(int n, struct dog_entry *rec)
{
char dog[SZ_NAME];
int j;
int flag = 0;
flag = find_dog(0, rec);
if(flag == 1)
printf("Record exists\n");
else
printf("No such record exists\n");
}
In find_dog() on line 161:
fread(&rec, sizeof(struct dog_entry), 1, f);
rec is already a pointer, so you shouldn't take its address.
You've got the same problem in view_dog() on line 126.
I found this out by running a program called Valgrind, which you should definitely get and learn how to use if you are a C programmer.

Resources