Bug fix for Dog Database - c

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.

Related

How to delete a record from FILE *fp in C?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void Main_Menu();
void add_bookid();
void search_book();
void delete_book();
void mod_book();
void appExit();
void prompt();
typedef struct
{
int dd;
int mm;
int yy;
}DATE;
struct book
{
char author[10];
char ID[10];
DATE date;
char Btitle[10];
char Bpub[10];
};
struct book books;
int main()
{
Main_Menu();
return 0;
}
//Main Menu
void Main_Menu()
{
int choice;
while(1)
{
printf("\n=================================================");
printf("\n======= INVENTORY AND MONITORING OF BOOKS =======");
printf("\n=================================================");
printf("\n[1] Add Book ID\n");
printf("[2] Search Book\n");
printf("[3] Delete a Book\n");
printf("[4] Edit Book Info\n");
printf("[5] Exit\n");
printf("\n=================================================");
printf("\nEnter your choice: ");
scanf("%d",&choice);
printf("\n=================================================");
switch(choice)
{
case 1:
add_bookid();
break;
case 2:
search_book();
break;
case 3:
delete_book();
break;
case 4:
mod_book();
break;
case 5:
appExit();
break;
default:
printf("\n INVALID INPUT!");
prompt();
break;
}
}
}
void add_bookid()
{
int book [10];
int a;
printf("\n------------------ ADD BOOKS ------------------");
printf("\n----------You can add up to 10 books-----------");
printf("\n=================================================");
printf("\n How many books you will add?: ");
scanf("%d", &a);
int isFound = 0;
for(int i=0; i<a;i++)
{
FILE *fp;
fp = fopen("book.txt","ab+");
fflush(stdin);
printf("\n---------------------------------------");
printf("\n[%d]Add Book ID: ", i+1);scanf("%s",books.ID);
printf("\nAdd Book Title: ");scanf("%s",books.Btitle);
printf("\nAdd Author: ");scanf("%s",books.author);
printf("\nAdd Date of Publication: ");
printf("\nEnter Month (MM): ");scanf("%d", &books.date.mm);
printf("\nEnter Date (dd): ");scanf("%d", &books.date.dd);
printf("\nEnter Year(yyyy): ");scanf("%d", &books.date.yy);
printf("\nPublisher: ");scanf("%s",books.Bpub);
fwrite(&books, sizeof(books), 1, fp);
fclose(fp);
}
printf("\n-------------------------------------------------");
prompt();
}
void search_book()
{
system("cls");
printf("\n------------------ SEARCH BOOKS ------------------");
char b_id[10];
int isFound = 0;
printf("\nEnter Book ID to Search: ");fflush(stdin);
gets(b_id);
FILE *fp;
fp = fopen("book.txt","rb");
while(fread(&books,sizeof(books),1,fp) == 1)
{
if(strcmp(b_id,books.ID) == 0)
{
isFound = 1;
break;
}
}
if(isFound == 1)
{
printf("\nThe record is Found");
printf("\n---------------------------------------");
printf("\nBook Title:%s ", books.Btitle);
printf("\nAuthor:%s ", books.author);
printf("\nDate of Publication: %d - %d - %d ", books.date.mm,books.date.dd, books.date.yy);
printf("\nPublisher: %s ", &books.Bpub);
}
else
{
printf("Sorry, No record found\n");
printf("\n=========================================");
}
fclose(fp);
printf("\n-------------------------------------------------");
prompt(); // return to main menu
}
void delete_book()
{
system("cls");
printf("\n------------------ DELETE BOOKS ------------------");
char b_id[10];
int isFound = 0;
printf("\nEnter Book ID to Delete: ");fflush(stdin);
gets(b_id);
FILE *fp, *temp;
fp = fopen("book.txt","rb");
temp = fopen("temp.txt", "wb");
while(fread(&books, sizeof(books),1,fp) == 1){
if(strcmp(b_id, books.ID) == 0){
fwrite(&books,sizeof(books),1,temp);
}
}
fclose(fp);
fclose(temp);
remove("book.txt");
rename("temp.txt","book.txt");
printf("The record is successfully deleted");
printf("\n-------------------------------------------------");
prompt();
}
void mod_book()
{
system("cls");
printf("\n------------------ EDIT BOOK INFO ------------------");
char b_title[10];
int isFound = 0;
printf("\nEnter Book Title to edit: ");fflush(stdin);
gets(b_title);
FILE *fp;
fp = fopen("book.txt","rb+");
while(fread(&books, sizeof(books),1,fp) == 1){
if(strcmp(b_title, books.Btitle) == 0){
fflush(stdin);
printf("\nAdd New Book ID: ");scanf("%s",books.ID);
printf("\nNew Book Title: ");scanf("%s",books.Btitle);
printf("\nNew Author: ");scanf("%s",books.author);
printf("\nDate of Publication: ");
printf("\nEnter New Month (MM): ");scanf("%s", &books.date.mm);
printf("\nEnter New Date (dd): ");scanf("%s", &books.date.dd);
printf("\nEnter New Year(yyyy): ");scanf("%s", &books.date.yy);
printf("\nNew Publisher: ");scanf("%s",books.Bpub);
printf("\nInformation Successfully Edited ");
fseek(fp,-sizeof(books), SEEK_CUR);
fwrite(&books,sizeof(books), 1, fp);
isFound = 1;
break;
}
}
if(!isFound){
printf("No Record Found!");
}
fclose(fp);
printf("\n-------------------------------------------------");
prompt(); // return to main menu
}
void appExit()
{
printf("\n == Thank you for using the App! == \n");
}
void prompt()
{
printf("\nPress 1 if you want to go back to Main Menu, Press any key to Exit: ");
int ans;
scanf("%d",&ans);
if(ans == 1)
{
system("cls");
Main_Menu();
}
else
appExit();
}
Let's say that a user add a record,
book id: 1,
title: xyxy,
author: jho,
date of publication, 12 - 12 - 2012,
then the user select another function which is 3,
delete_book,
Enter Book ID to Delete: 1.
then it will print "The record is successfully deleted"
When the user select another function, search_book();
The output should be "Sorry, No record found"
But my code still prints the recorded data even if the user already delete it.
How to fix this?

Hash table doesn't remove

I'm trying to make those 3 operations, add, remove and search. But when I try to remove some values it doesn't work,I'd like to know what I'm doing wrong in this function and/or if I wrote the others functions correctly. here is the whole code.
if I try to remove the same value twice: free(): double free detected in tcache 2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define size_table 10
typedef struct Citizen citizen;
typedef struct Citizen{
char name[20];
int age;
citizen *next;
citizen *table[size_table];
} citizen;
int hash_function(int age){
return 10 - 2 - age % (size_table-2);
}
citizen *hash_add(citizen *tab, int age, char *name){
int position = hash_function(age);
citizen *new_citizen = (citizen*)malloc(sizeof(citizen));
new_citizen->next = tab->table[position];
new_citizen->age = age;
strcpy(new_citizen->name,name);
tab->table[position] = new_citizen;
return new_citizen;
}
citizen *hash_search(citizen *tab, int age){
int position = hash_function(age);
citizen *new_search = tab->table[position];
while(new_search != NULL){
if(new_search->age == age) return new_search;
new_search = new_search->next;
}
return NULL;
}
void hash_delete(citizen *tab, int age){
int position = hash_function(age);
citizen *new_delete = hash_search(tab,age);
new_delete = tab->table[position];
free(new_delete);
}
void clean_screen(){ system("clear"); }
void menu(){
"\033[0;32mi -Insert \n"
"\033[0;33mr -Remove \n"
"\033[0;34ms -Search \n"
);
}
int main(){
clean_screen();
menu();
citizen ct;
int age;
char get_name;
char choice;
while(scanf("%c",&choice) != EOF){
switch(choice){
case 'i':
clean_screen();
printf("Insira a idade: ");
scanf("%d",&age);
printf("Insira o nome: ");
scanf("%c ",&get_name);
hash_add(&ct,age,&get_name);
printf("Elemento adicionado ");
clean_screen();
menu();
break;
case 'r':
clean_screen();
printf("Remover a idade: ");
scanf("%d",&age);
hash_delete(&ct, age);
clean_screen();
menu();
break;
case 's':
clean_screen();
printf("Digite a idade: ");
scanf("%d",&age);
citizen *get_search = hash_search(&ct,age);
clean_screen();
if(get_search != NULL) printf("Idade %d encontrada\n", age);
else printf("idade %d não exise\n",age);
menu();
break;
}
}
return 0;
}

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; //
}

Console app menu not working in C

guys! So I have an assignment to create a structure that includes variables based on what information I need to store and to bring out a menu that calls different functions and does different things. The problems is that for some reason my createFile function is not working at all and I've been looking for errors for 2 days and I simply cannot spot where this is coming from.
Ignore the changeStud funcion as I'm still working on it. I simply want to create my file when I enter the name for it and then chose the nnumber of the function. (in my case > enter filename> enter 1> it just loops the menu function and it should create a file)
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
char ime[50];
char fn[10];
int ocfiz, ocmat, ocpro;
};
char filename[20];
FILE *fd;
Student ps;
void createFile() {
fd = fopen(filename, "wb");
fclose(fd);
printf("File created!\n");
}
void readStud(Student *s) {
printf("Enter data for new student");
getchar();
printf("Enter student name:");
gets_s(s->ime);
printf("\nEnter FN:");
scanf_s("%s", s->fn);
printf("\nEnter marks for Maths, Programming, Physics");
scanf_s("%d %d %d", &s->ocmat, &s->ocpro, &s->ocfiz);
getchar();
}
void addStud() {
fd = fopen(filename, "a+b");
char c;
do {
readStud(&ps);
fwrite(&ps, sizeof(ps), 1, fd);
printf("More Students? (y/n) : ");
c = getchar(); getchar();
} while (c == 'y');
fclose(fd);
}
void writeAllStud() {
fd = fopen(filename, "rb");
printf("students in file\n");
fread(&ps, sizeof(ps), 1, fd);
while (!feof(fd)) {
printf("%s fn: %s ocmat: %d ocpro: %d ocfiz: %d", ps.ime, ps.fn, ps.ocmat, ps.ocpro, ps.ocfiz);
fread(&ps, sizeof(ps), 1, fd);
}
fclose(fd);
}/*
void changeStud() {
char fn2[50];
printf("enter FN:");
gets_s(fn2);
fd = fopen(filename, "r+b");
fread(&ps, sizeof(ps), 1, fd);
while (!feof(fd)) {
if (strcmp(ps.fn, fn2)==0) {
fseek(fd, -(long) sizeof(ps), SEEK_CUR);
fwrite(&ps, sizeof(ps, 1, fd));
break;
}
}
}*/
void Avg() {
}
void exportData() {
FILE *txt;
txt = fopen("students.txt", "wt");
fd = fopen(filename, "rb");
fread(&ps, sizeof(ps), 1, fd);
while (!feof(fd)) {
fprintf(txt, "%s %s marks fiz%d mat%d prog%d\n", ps.fn, ps.ime, ps.ocfiz, ps.ocmat, ps.ocpro);
fread(&ps, sizeof(ps), 1, fd);
}
fclose(fd);
fclose(txt);
printf("students have been written to a text file.\n");
}
void main() {
printf("Enter file name:");
gets_s(filename);
int c;
do {
printf("\nMenu:\n");
printf("0 Exit\n");
printf("1 Create file\n");
printf("2 Add new student data\n");
printf("3 Change data from FN\n");
printf("4 AVG marks for maths, programming, physics\n");
printf("5 export all AVG marks to .txt file\n");
scanf("%d", &c);
switch (c) {
case 1: createFile; break;
case 2: addStud; break;
//case 3: changeStud; break;
case 4: Avg; break;
case 5: exportData; break;
}
} while (c != 0);
}
i think you should use your struct variable like this:
struct Student {
char ime[50];
char fn[10];
int ocfiz, ocmat, ocpro;
}ps;
or use
struct Student ps;
instead of just student ps,or you can decleare it in main function..And passing a struct in a functin is
void readStud( struct Student *s)() {
//your code...
}

input of data in a FILE

i have to input the data into a FILE * (this is in C and using codeblocks), the data is a struct containing 3 char[ ] an 1 double, i dont know why when i print the file it repeats the last struct twice and in "dni" it puts 0.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char dni[9];
char nombre[100], apellido[100];
double monto_adeudado;
} t_datos;
void carga_del_archivo(char[]);
t_datos carga_struct(t_datos);
int main()
{
char nombrearchivo[30];
printf("ingrese el nombre del archivo: ");
gets(nombrearchivo);
carga_del_archivo(nombrearchivo);
return 0;
}
void carga_del_archivo(char nombre[30])
{
FILE* ptrarch;
t_datos aux;
ptrarch = fopen(nombre, "ab");
if (ptrarch != NULL) {
do {
aux = carga_struct(aux);
fwrite(&aux, sizeof(t_datos), 1, ptrarch);
} while (strcmp(aux.dni, "0") != 0);
} else {
printf("ERROR\n");
}
}
t_datos carga_struct(t_datos aux)
{
printf("\ningrese el dni: ");
fflush(stdin);
gets(aux.dni);
if (strcmp(aux.dni, "0") == 0)
return aux;
printf("\ningrese el nombre: ");
fflush(stdin);
gets(aux.nombre);
fflush(stdin);
printf("\ningrese el apellido: ");
gets(aux.apellido);
fflush(stdin);
printf("\ningrese el monto adeudado: ");
scanf("%lf", &aux.monto_adeudado);
return aux;
}
Problem is here:
{
aux=carga_struct(aux);
fwrite(&aux,sizeof(t_datos),1,ptrarch);
}while(strcmp(aux.dni,"0")!=0);
When you enter 0 here aux=carga_struct(aux) you write it to the disk by fwrite on next line before checking this statement: while(strcmp(aux.dni,"0")!=0).

Resources