How to use Binary Search on array of string - c

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

Related

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

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

After I print from the struct using a file it doesn't work [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
a- Read and print the data from the file "detyra_day.dat"
b- Add another citizen when you know the IDNR is unique
c- Change the information of a citizen without changing IDNR
d- Create a "Permit to go outside" application for only 1 person per family per day
(the applicant can apply for another family member and the applicant must be over 18 years old)
and the "Permit to go outside" is granted from 8:00 to 17:00 which lasts 2 hours.
e- Check if a citizen does have permission to go outside (print IDNR, date and time).
f- Save
g- Print all "Permissions to go outside" for all citizens and families.
h- Print the list of 10 citizens that asked for the permission the most and 10 that asked the least (exclude the ones that didn't asked at all)
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <windows.h>
int permission;
int hour;
int minute;
int nr_people;
struct citizen{
char idnr[10];
char name[50];
char lname[50];
long int birthday;
int id_family;
};
struct birthday{
int year;
int month;
int day;
};
char fname[]={"detyra_day.dat"};
void readPeopleInfo(){
nr_people=0;
struct citizen s;
FILE *f;
f=fopen(fname,"r");
printf("\n========================================================\n\n");
printf("\t\t Details of all citizen \n\n");
printf("========================================================\n\n");
printf("IDNR\tname\tlname\tbirthday\tid_family\n\n");
if(f == NULL)
{
printf("Error opening file\n");
exit(1);
}
while(fread(&s,sizeof(struct citizen),1,f))
{
printf("%s\t",s.idnr);
printf("%s\t",s.name);
printf("%s\t",s.lname);
printf("%ld\t",s.birthday);
printf("%d\t\n\n",s.id_family);
nr_people++;
}
fclose(f);
printf("========================================================\n\n");
printf("Number of citizen = %d",nr_people);
}
void add(){
struct citizen s,s1;
int nr_people=5;
int found=0;
printf("\n Give the unique IDNR: ");
scanf("%s",&s1.idnr);
for(int i=0;i<nr_people;i++){
if(s1.idnr==s.idnr){
printf("The citizen with this IDNR exist");
found=1;
return;
}
}
if(found==0){
printf("The citizen with this IDNR doesn't 'exist");
strcpy(s.idnr,s1.idnr);
printf("\nGive the name of the citizen: ");
scanf("%s",s.name);
printf("\n Give the lname of the citizen: ");
scanf("%s",s.lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%ld",&s.birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d",&s.id_family);
nr_people++;
}
}
void change(){
struct citizen s[50];
char *idnr;
printf("\n IDNR of citizen: ");
scanf("%s",&idnr);
for(int i=0;i<nr_people; i++){
if (strcmp(s[i].idnr,idnr)==0){
printf("\nGive the name of the citizen: ");
scanf("%s",s[i].name);
printf("\n Give the lname of the citizen: ");
scanf("%s",s[i].lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%ld",&s[i].birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d",&s[i].id_family);
printf("\n Changed succesfully.");
return; }
printf("\n The change didn't happened.");
}
}
void permit(){
int permission;
struct birthday bday;
struct citizen s[50];
int age[nr_people];
SYSTEMTIME d;
GetLocalTime(&d);
for(int i=0;i<nr_people;i++){
if(bday.month>d.wMonth||(bday.month==d.wMonth&&bday.day>=d.wDay)){
age[i]=d.wYear-bday.year;
}
else{
age[i]=d.wYear-bday.year-1;
}
}
char *name;
char *lname;
char *chosenperson;
int id_family;
int i;
int apply=0;
int familymembers=0;
printf("Put your name: ");
scanf("%s",&name);
printf("Put your lname: ");
scanf("%s",&lname);
for (i=0;i<nr_people;i++){
if((strstr(name,s[i].name)==0&&strstr(lname,s[i].lname)==0&&age[i]>=18)){
printf("Your name is on the list and you are in the age to apply");
id_family=s[i].id_family;
apply=1;
}
}
if(apply==0){
printf("Your name is not on the list or you are not in the age to apply");
return;
}
struct citizen tmp;
for(i=0;i<nr_people;i++){
if(id_family==s[i].id_family){
tmp=s[50];
familymembers++;
}
}
for(i=0;i<familymembers;i++){
printf("%d. name: %10s",i+1,tmp.name);
}
apply=0;
printf("Give the name of the person from your family that you want to apply: ");
scanf("%s",chosenperson);
printf("\nYou chose: ");
for(i=0;i<familymembers;i++){
if(strstr(chosenperson,tmp.name)==0){
printf("%s",tmp.name);
apply=1;
}
}
if(apply==0){
printf("\nThe selected name is not on the list");
return;
}
printf("\nChose a time between 8:00 and 17:00: ");
float timez;
int hour;
int minute;
scanf("%f",&timez);
if(timez>=8.00&&timez<=17.00){
hour=timez;
minute=(timez-hour)*100;
if(minute>59){
printf("Minutes are placed wrong");
return;
}
printf("\nYour application to go out from %f to %f is accepted!",timez,timez+2);
permission=1;
}
else{
printf("You have chosen the wrong time");
return;
}
}
void control(){
permit();
struct citizen s[50];
SYSTEMTIME d;
GetLocalTime(&d);
int g=permission;
for(int i=0;i<nr_people;i++){
if(g==1){
printf("\n The citizen with IDNR: %s Date: %d/%d/%d Time: %d.%d has applied to go outside",s[nr_people].idnr,d.wYear,d.wMonth,d.wDay,hour,minute);
}
}
}
void save(){
struct citizen s[50];
FILE *f;
f=fopen("detyra_day.dat","w");
if (f==NULL){
printf("\n Error on the file");
return;
}
for(int i=0;i<nr_people; i++){
fwrite(&s[i],sizeof(struct citizen),1,f);
}
}
int main(){
char selection;
do{
printf("\n=============================");
printf("\n 1 - Read and print the data from the file detyra_day.dat");
printf("\n 2 - Add a citizen");
printf("\n 3 - Change a citizen");
printf("\n 4 - Create a Permit to go outside");
printf("\n 5 - Control the permission");
printf("\n 6 - Save");
printf("\n 7 - Print all Permissions to go outside for all citizens and families");
printf("\n 8 - Print the list of 10 citizens that asked for the permission the most and 10 that asked the least (exclude the ones that didn't asked at all)");
printf("\n 9 - Exit");
printf("\n-----------------------------");
printf("\n Zgjedhja : ");
selection=getch();
switch(selection){
case '1':
readPeopleInfo();
break;
case '2':
add();
break;
case '3':
change();
break;
case '4':
permit();
break;
case '5':
control();
break;
case '6':
save();
break;
case '9':
exit(0);
}
getch();
} while(selection!='9');
return 0;
}
After I press Run and try number 1 which is read and print it prints every person as 1 not as the struct says. For example I want to print it like this:
IDNR: H65328040Q
Name: Azbie
Lname: Gockaj
Birthday (YYYYMMDD format):19760328
ID_Family: 1
Instead I get:
INDR: Name: Lname: Birthday: ID_Family:
and then every person ordered
This is the detyra_day.dat file
H65328040Q Azbie Gockaj 19760328 1
J70507042S Ledion Celaj 19970507 1
G70312202S Pellumb Osmani 19670312 2
H45827189P Albina Osmani 19740827 2
There are a number of errors.
First, you need a global array of struct citizen instead of having a function scoped struct citizen in each function.
In struct citizen, idNr was too small to contain a 10 digit ID number. It has to be [at least] one more to account for the EOS char at the end of the string.
Using fread and fwrite to access the data file. They are for binary files, but you have a text file. You need to use fscanf and fprintf respectively.
Using (e.g.) a [function scoped] char *name;. This is a pointer to a char [array/string] and it is uninitialized. Change this to char name[100];
Using strstr instead of strcmp.
Use of scanf or fscanf was inconsistent. If you had compiled with -Wall -Wextra to enable warnings [gcc], they would have become apparent.
It's bad practice to intermix getch [fgetc] and scanf on the same stream.
For consistency, I've added a prompt function instead of the various printf(...); scanf(...); sequences for prompting the user.
You didn't really use your struct birthday in the code.
Here's the cleaned up code. Some basics have been tested, but there are still some issues I couldn't get to. In most places, I've used #if 0 to denote your old code [vs. my new code]
#include <stdio.h>
#include <string.h>
#ifndef __linux__
#include <conio.h>
#include <dos.h>
#endif
#include <windows.h>
#ifdef __linux__
#include <time.h>
int
getch(void)
{
char buf[1000];
int chr;
if (fgets(buf,sizeof(buf),stdin) != 0)
chr = buf[0];
else
chr = -1;
return chr;
}
WINBASEAPI VOID WINAPI
GetLocalTime(LPSYSTEMTIME lps)
{
time_t tod;
struct tm *tm;
tod = time(NULL);
tm = localtime(&tod);
lps->wYear = tm->tm_year + 1900;
lps->wMonth = tm->tm_mon + 1;
lps->wDayOfWeek = tm->tm_wday;
lps->wDay = tm->tm_mday;
lps->wHour = tm->tm_hour;
lps->wMinute = tm->tm_min;
lps->wSecond = tm->tm_sec;
lps->wMilliseconds = 0;
}
#endif
int permission;
int hour;
int minute;
int nr_people;
struct birthday {
int year;
int month;
int day;
};
struct citizen {
#if 0
char idnr[10];
#else
char idnr[10 + 1];
#endif
char name[50];
char lname[50];
struct birthday birthday;
int id_family;
};
#define CITMAX 50
struct citizen citlist[CITMAX];
char fname[] = { "detyra_day.dat" };
void
prompt(const char *str,char *buf)
{
printf("%s: ",str);
fflush(stdout);
fgets(buf,100,stdin);
char *cp = strchr(buf,'\n');
if (cp != NULL)
*cp = 0;
}
void
getbday(const char *buf,struct birthday *bday)
{
sscanf(buf,"%4d%2d%2d",&bday->year,&bday->month,&bday->day);
}
void
loadPeopleInfo()
{
struct citizen *s;
char birthday[100];
FILE *f;
nr_people = 0;
f = fopen(fname, "r");
if (f == NULL) {
printf("Error opening file\n");
exit(1);
}
while (1) {
s = &citlist[nr_people];
if (fscanf(f," %s %s %s %s %d\n",
s->idnr,s->name,s->lname,birthday,&s->id_family) != 5)
break;
getbday(birthday,&s->birthday);
nr_people++;
if (nr_people >= CITMAX)
break;
}
fclose(f);
}
void
printPeopleInfo()
{
struct citizen *s;
printf("\n========================================================\n\n");
printf("\t\t Details of all citizen \n\n");
printf("========================================================\n\n");
printf("IDNR\t\tname\tlname\tbirthday\tid_family\n\n");
for (int i = 0; i < nr_people; ++i) {
s = &citlist[i];
printf("%s\t", s->idnr);
printf("%s\t", s->name);
printf("%s\t", s->lname);
struct birthday *bday = &s->birthday;
printf("%4.4d%2.2d%2.2d\t",bday->year,bday->month,bday->day);
printf("%d\t\n", s->id_family);
}
printf("========================================================\n\n");
printf("Number of citizen = %d\n", nr_people);
}
void
add()
{
#if 0
struct citizen s, s1;
#else
struct citizen *s;
struct citizen s1;
#endif
#if 0
int nr_people = 5;
#endif
int found = 0;
char buf[100];
#if 0
printf("\n Give the unique IDNR: ");
scanf("%s\n", &s1.idnr);
#else
prompt("Give the unique IDNR",s1.idnr);
#endif
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
#if 0
if (s1.idnr == s->idnr) {
#else
if (strcmp(s1.idnr,s->idnr) == 0) {
printf("The citizen with this IDNR exist\n");
found = 1;
return;
}
#endif
}
if (found == 0) {
s = &citlist[nr_people];
printf("The citizen with this IDNR doesn't 'exist\n");
strcpy(s->idnr, s1.idnr);
#if 0
printf("\nGive the name of the citizen: ");
scanf("%s\n", s->name);
#else
prompt("Give the name of the citizen",s->name);
#endif
#if 0
printf("\n Give the lname of the citizen: ");
scanf("%s\n", s->lname);
#else
prompt("Give the lname of the citizen",s->lname);
#endif
#if 0
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%s\n",buf);
#else
prompt("Give the birthday of the citizen in the format YYYYMMDD",buf);
#endif
getbday(buf,&s->birthday);
#if 0
printf("\n Give the ID of the family of the citizen: ");
scanf("%d\n", &s->id_family);
#else
prompt("Give the ID of the family of the citizen",buf);
sscanf(buf,"%d", &s->id_family);
#endif
nr_people++;
}
}
void
change()
{
struct citizen *s;
char birthday[100];
#if 0
char *idnr;
#else
char idnr[100];
#endif
printf("\n IDNR of citizen: ");
#if 0
scanf("%s", &idnr);
#else
scanf("%s\n",idnr);
#endif
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
if (strcmp(s->idnr, idnr) == 0) {
printf("\nGive the name of the citizen: ");
scanf("%s\n", s->name);
printf("\n Give the lname of the citizen: ");
scanf("%s\n", s->lname);
printf("\n Give the birthday of the citizen in the format YYYYMMDD: ");
scanf("%s\n", birthday);
getbday(birthday,&s->birthday);
printf("\n Give the ID of the family of the citizen: ");
scanf("%d\n", &s->id_family);
printf("\n Changed succesfully.");
return;
}
#if 0
printf("\n The change didn't happened.");
#endif
}
#if 1
printf("\n The change didn't happened.");
#endif
}
void
permit()
{
#if 0
struct birthday bday;
#else
struct birthday *bday;
#endif
struct citizen *s;
int age[nr_people];
SYSTEMTIME d;
GetLocalTime(&d);
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
bday = &s->birthday;
if (bday->month > d.wMonth ||
(bday->month == d.wMonth && bday->day >= d.wDay)) {
age[i] = d.wYear - bday->year;
}
else {
age[i] = d.wYear - bday->year - 1;
}
}
#if 0
char *name;
char *lname;
char *chosenperson;
#else
char name[100];
char lname[100];
char chosenperson[100];
#endif
int id_family;
int i;
int apply = 0;
int familymembers = 0;
#if 0
printf("Put your name: ");
scanf("%s", &name);
#else
prompt("Put your name",name);
#endif
#if 0
printf("Put your lname: ");
scanf("%s", &lname);
#else
prompt("Put your lname",lname);
#endif
// NOTE/BUG: use strcmp instead of strstr
for (i = 0; i < nr_people; i++) {
s = &citlist[i];
if ((strcmp(name, s->name) == 0 && strcmp(lname, s->lname) == 0 &&
age[i] >= 18)) {
printf("Your name is on the list and you are in the age to apply [%d]\n",age[i]);
id_family = s->id_family;
apply = 1;
}
}
if (apply == 0) {
printf("Your name is not on the list or you are not in the age to apply");
return;
}
struct citizen tmp[nr_people];
for (i = 0; i < nr_people; i++) {
s = &citlist[i];
if (id_family == s->id_family) {
tmp[familymembers++] = *s;
}
}
for (i = 0; i < familymembers; i++) {
printf("%d. name: %10s\n", i + 1, tmp[i].name);
}
apply = 0;
prompt("Give the name of the person from your family that you want to apply ",chosenperson);
printf("\nYou chose: ");
for (i = 0; i < familymembers; i++) {
if (strcmp(chosenperson, tmp[i].name) == 0) {
printf("%s", tmp[i].name);
apply = 1;
}
}
if (apply == 0) {
printf("\nThe selected name is not on the list");
return;
}
printf("\nChose a time between 8:00 and 17:00: ");
float timez;
int hour;
int minute;
scanf("%f", &timez);
if (timez >= 8.00 && timez <= 17.00) {
hour = timez;
minute = (timez - hour) * 100;
if (minute > 59) {
printf("Minutes are placed wrong");
return;
}
printf("\nYour application to go out from %f to %f is accepted!",
timez, timez + 2);
permission = 1;
}
else {
printf("You have chosen the wrong time");
return;
}
}
void
control()
{
permit();
SYSTEMTIME d;
struct citizen *s;
GetLocalTime(&d);
int g = permission;
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
if (g == 1) {
printf("\n The citizen with IDNR: %s Date: %d/%d/%d Time: %d.%d has applied to go outside",
s->idnr, d.wYear, d.wMonth, d.wDay, hour, minute);
}
}
}
void
save()
{
struct citizen *s;
struct birthday *bday;
FILE *f;
f = fopen("detyra_day.dat", "w");
if (f == NULL) {
printf("\n Error on the file");
return;
}
for (int i = 0; i < nr_people; i++) {
s = &citlist[i];
fprintf(f,"%s ", s->idnr);
fprintf(f,"%s ", s->name);
fprintf(f,"%s ", s->lname);
bday = &s->birthday;
fprintf(f,"%4.4d%2.2d%2.2d ",bday->year,bday->month,bday->day);
fprintf(f,"%d\n", s->id_family);
}
#if 1
fclose(f);
#endif
}
int
main()
{
char buf[100];
int selection = 0;
loadPeopleInfo();
do {
printf("\n=============================");
printf("\n 1 - Read and print the data from the file detyra_day.dat");
printf("\n 2 - Add a citizen");
printf("\n 3 - Change a citizen");
printf("\n 4 - Create a Permit to go outside");
printf("\n 5 - Control the permission");
printf("\n 6 - Save");
printf("\n 7 - Print all Permissions to go outside for all citizens and families");
printf("\n 8 - Print the list of 10 citizens that asked for the permission the most and 10 that asked the least (exclude the ones that didn't asked at all)");
printf("\n 9 - Exit");
printf("\n-----------------------------\n");
prompt("Zgjedhja",buf);
selection = buf[0];
switch (selection) {
case '1':
printPeopleInfo();
break;
case '2':
add();
break;
case '3':
change();
break;
case '4':
permit();
break;
case '5':
control();
break;
case '6':
save();
break;
#if 0
case '9':
exit(0);
#endif
}
#if 0
getch();
#endif
} while (selection != '9');
return 0;
}

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 *

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

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