Bus error while simply integer scanf sequence in C program - c

I have to take integer inputs and end the while loop if input is -1 in the following format in C:
111 1 1
111 1 1
111 1 1
-1
My code get bus error after 3rd scanf in the main function (end of the code). I know this is about white spaces but i have no idea to solve it. I am testing on MacBook with M1 if it is important. Btw print("break")s for just testing, i don't want to any junk print or scan.
#include <stdio.h>
#include <stdlib.h>
struct employee{
int ID;
int freeAt;
int totalTime;
struct employee *next;
};
struct customer{
int ID;
int startTime;
int processTime;
int waitingTime;
int helper;
struct customer *front;
struct customer *rear;
struct customer *next;
};
typedef struct employee employee;
typedef struct customer customer;
void new_employer(employee *top, int id){ //Insert employees by id
employee *ptr;
ptr = (employee*)malloc(sizeof(employee));
ptr->ID = id;
ptr->freeAt = 0;
ptr->totalTime = 0;
if (top == NULL){
ptr->next = NULL;
top = ptr;
}
else{
ptr->next = top;
top = ptr;
}
}
void help_customer(customer *c, employee *top){ //Match customer with suitable employee
employee *ptr;
ptr = (employee*)malloc(sizeof(employee));
ptr = top;
if (top==NULL){
c->startTime = c->startTime + 1;
c->waitingTime++;
help_customer(c,ptr);
}
if(c->startTime>=top->freeAt){
c->helper = top->ID;
top->freeAt = c->startTime + c->processTime;
top->totalTime = top->totalTime + c->processTime;
}
else{
help_customer(c, top->next);
}
}
void new_customer(customer *c, employee *top, int id, int start, int process){ //New customer
customer *ptr;
ptr = (customer*)malloc(sizeof(customer));
ptr->ID = id;
ptr->startTime = start;
ptr->processTime = process;
ptr->waitingTime = 0;
help_customer(ptr,top);
if (c->front == NULL){
c->front = ptr;
c->rear = ptr;
c->next = NULL;
}
else{
c->rear->next = ptr;
c->rear = ptr;
c->rear->next = NULL;
}
}
void customerStats(customer *c){ //Printing customer stats at the end of the transactions
customer *ptr;
ptr = (customer*)malloc(sizeof(customer));
ptr = c->front;
if(ptr == NULL){
printf("\nQUEUE IS EMPTY");
}
else{
printf("\n");
while (ptr!=c->rear){
printf("%d ", ptr->ID);
printf("%d ", ptr->helper);
printf("%d ", ptr->startTime);
printf("%d ", ptr->processTime);
printf("%d\n", ptr->waitingTime);
ptr = ptr->next;
}
printf("%d ", ptr->ID);
printf("%d ", ptr->helper);
printf("%d ", ptr->startTime);
printf("%d ", ptr->processTime);
printf("%d\n", ptr->waitingTime);
}
}
void employeeStats(employee *top){ //Printing employee stats at the end of the transactions
employee *ptr;
ptr = (employee*)malloc(sizeof(employee));
ptr = top;
if (top==NULL){
printf("\nSTACK IS EMPTY");
}
else{
while (ptr!=NULL){
printf("%d ", ptr->ID);
printf("%d\n", ptr->totalTime);
ptr = ptr->next;
}
}
}
int main(){
employee *e;
for(int i=1;i>7;i++){
new_employer(e,i);
}
customer *c;
int id;
int start;
int process;
while(1){ //********I GET BUS ERROR HERE ON 3RD SCANF**************
scanf("%d", &id);
printf("break1");
if (id==-1){
break;
}
scanf("%d", &start);
printf("break2");
scanf("%d", &process);
printf("break3");
new_customer(c,e,id,start,process);
}
customerStats(c);
employeeStats(e);
}
This is the terminal:
111
break11
break21
zsh: bus error ./main

It helps if you write minimal code to begin with, and get that working before adding more.
Here's a partial correction that shows why you are getting undefined behaviour (crashing). Read each line and understand why and how it differs from your code. Once that is understood, you can (cautiously, step-by-step) add one more element at a time and test, test, test as you build up toward your objective.
typedef struct employee {
int ID;
int freeAt;
int totalTime;
struct employee *next;
} employee_t;
employee_t *new_employeEEEE( employee_t *top, int id ) { //Insert employees by id
employee_t *ptr = (employee_t*)calloc( 1, sizeof(*ptr) ); // use calloc()
// Omitting check of calloc failing
ptr->ID = id;
ptr->next = top; // reverse sequence, but at least it works...
return ptr;
}
int main() {
employee_t *e = NULL;
// for( int i=1; i > 7;i++ ) !!!!
for( int i = 1; i < 7; i++ )
e = new_employeEEEE( e, i );
i = 1;
for( employee *p = e; p; p = p->next )
printf( "emp #%d has id: %d\n", i++, p->ID );
return 0;
}
Output:
emp #1 has id: 6
emp #2 has id: 5
emp #3 has id: 4
emp #4 has id: 3
emp #5 has id: 2
emp #6 has id: 1

Related

segmentation fault after free-ing node in hashtable

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define size 9900
int count = 1;
struct membership {
char name[100];
char gender[100];
char code[100];
int age;
int weight;
struct membership* next;
}*table[size];
typedef struct membership member;
member *newMember(char name[], char gender[], char code[], int age, int weight){
member *node = (member*)malloc(sizeof(member));
strcpy(node->name, name);
strcpy(node->gender, gender);
strcpy(node->code, code);
node->age = age;
node->weight = weight;
node->next = NULL;
return node;
}
int asciiSum(char str[]){
int sum = 0;
for(int i = 0; str[i] != '\0'; i++){
sum += str[i];
}
return sum;
}
int hash(char code[]){
return asciiSum(code)%size;
}
// insert recursive
member *insertRec(member *curr, char name[], char gender[], char code[], int age, int weight){
if (!curr){
return newMember(name, gender, code, age, weight);
}
curr->next = insertRec(curr->next, name, gender, code, age, weight);
return curr;
}
// insert biasa
void insert(char name[], char gender[], char code[], int age, int weight){
int key = hash(code);
table[key] = insertRec(table[key], name, gender, code, age, weight);
}
void viewMember(){
printf("| %-5s | %-20s | %-20s | %-20s | %-20s | %-15s |\n",
"no", "member name", "member age", "member weight", "member gender", "member code");
int j = 0;
for (int i = 0; i < size; i++) {
member *curr = table[i];
while (curr) {
printf("| %-5d | %-20s | %-20d | %-20d | %-20s | %-15s |\n",
++j, curr->name, curr->age, curr->weight, curr->gender, curr->code);
curr = curr->next;
}
}
}
member *searchRec(member *curr, char *code){
if (!curr) return NULL;
if(!strcmp(curr->code, code))return curr;
return searchRec(curr->next, code);
}
member *deleteRec(member *curr, char *code){
if (!curr) return NULL;
if (!strcmp(curr->code, code)){
free(curr);
return curr->next;
}
curr->next = deleteRec(curr->next, code);
return curr;
}
void deleteProduct(char *code){
int key = hash(code);
member *node = searchRec(table[key], code);
if (!node) {
printf("%s not found\n", code);
return;
}
printf("Deleted %s\n", node->name);
table[key] = deleteRec(table[key], code);
}
int main(){
insert("tono", "male", "61TOM102", 21, 40);
insert("tini", "female", "61TIF102", 21, 40);
insert("didi", "male", "102DIM102", 21, 40);
deleteProduct("61TOM102");
viewMember();
return 0;
}
The code above will produce zsh: segmentation fault.
What i expected : tono node got freed and the array got printed as normal but without tono
What actually resulted : zsh: segmentation fault
i think the error is either in deleteRec function or viewMember function.
i think after i free(curr) it somehow still there but as an invalid memory ?
i'm really stumped, can someone give me a hint ?
Thank you in advance
PS. when i try running the code on online compiler there's no problem, is the problem with my hardware ?

im trying to read data from a file and disturb them into linked nodes, however, when i check the linked nodes it says it's empty

So what I'm trying to do is read inputs from a file and disturb the input into nodes, after that I link the nodes together so I get a linked list, however, when I check the linked list it says the list is empty, not sure where the problem is but i assume it's something with the nodes not being linked together correctly
this is the code
#include <stdio.h>
#include <stdlib.h>
#include <intrin.h>
#include <string.h>
void Load_bus_information();
void Load_pass_information();
int Assign_passengers_print_buss_information();
int Print_specific_bus_info();
int Print_unmatched_passengers();
int Add_new_passenger();
void Delete_passenger();
int Delete_bus_number();
char source_all[150][150];
char destination_all[150][150];
int id_all [150];
char time_all[250][250];
int date_all [150];
///////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
int bus_number[150];
int bus_date[150];
char bus_time[155][150];
char sourceBus_all[150][150];
char destinationBus_all[150][150];
int capacity[150];
int price[150];
///////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
struct passenger
{
int id_p ;
int date_p ;
char time_p[150] ;
char sour_p[150];
char des_p[150];
struct passenger* Next;
};
struct bus
{
int num ;
int date_b;
char time_b ;
char des_b;
char sour_p;
struct bus* Next;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void insert(int id2,int date2,char time2[], char sou2[], char dest2[], struct passenger* L );
struct passenger* FindPrevious(int X, struct passenger* L);
struct passenger* IsLast(struct passenger* P, struct passenger* L);
int isEmpty(struct passenger* L);
void Delete(int X, struct passenger* L);
struct passenger *start=NULL;
struct passenger* L;
void PrintList( struct passenger *L);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
int task=0;
do
{
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("1. Load the bus information file. \n");
printf("2. Load the passenger information file. \n");
printf("3. Assign passengers and print assignment information of all busses.\n");
printf("4. Print a specific bus information along with its passengers information (names and IDs).\n");
printf("5. Print unmatched passengers. \n");
printf("6. Add new passenger.\n");
printf("7. Delete passenger.\n");
printf("8. Delete bus number.\n");
printf("9. Exit.\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
scanf("%d",&task);
switch(task)
{
case 1:
Load_bus_information();
break;
case 2:
Load_pass_information();
break;
case 3:
Assign_passengers_print_buss_information();
break;
case 4:
Print_specific_bus_info();
break;
case 5:
Print_unmatched_passengers();
break;
case 6:
Add_new_passenger();
break;
case 7:
Delete_passenger();
break;
case 8:
Delete_bus_number();
break;
default:
exit(-1);
//}
}
}
while (task!=9);
return 0;
}
//********************************
void insert(int id2,int date2,char time2[], char sou2[], char dest2[], struct passenger* L )
{
struct passenger *temp2 = NULL, *current = NULL, *head = NULL;
// L = head ;
temp2 = (struct passenger*)malloc(sizeof(struct passenger));
// head = NULL; head = (struct passenger*)malloc(sizeof(struct passenger));
temp2->Next=NULL;
temp2->id_p = id2;
temp2->date_p= date2;
strcpy(temp2->time_p, time2);
strcpy(temp2->sour_p, sou2);
strcpy(temp2->des_p, dest2);
temp2->Next = NULL;
// temp2->Next = head->Next;
//head->Next= temp2;
if(head ==NULL)
{
head = temp2;
current = temp2;
}
else
{
current->Next = temp2 ;
current = current->Next ;
}
printf(" %-10d %-10d %-10s %-10s %-10s \n",temp2->id_p, temp2->date_p, temp2->time_p,temp2->sour_p,temp2->des_p);
head = L ;
}
/*
void insert(int id2,int date2,char time2[], char sou2[], char dest2[] , struct passenger **head)
{
//create a new node
struct passenger *temp2 = malloc(sizeof(struct passenger));
temp2->id_p = id2;
temp2->date_p= date2;
strcpy(temp2->time_p, time2);
strcpy(temp2->sour_p, sou2);
strcpy(temp2->des_p, dest2);
temp2->Next= NULL;
if(*head == NULL)
*head = temp2;
printf(" %d %d %s %s %s \n",temp2->id_p, temp2->date_p, temp2->time_p,temp2->sour_p,temp2->des_p);
//if head is NULL, it is an empty list
}*/
struct passenger* FindPrevious(int X, struct passenger* L)
{
struct passenger* P;
struct passenger* S = L -> Next;
P = L;
while(P->Next != NULL && P->Next->id_p != X)
P = P->Next;
S = S->Next;
return P;
}
struct passenger* IsLast(struct passenger* P, struct passenger* L)
{
return P->Next == NULL ;
}
int isEmpty(struct passenger* L)
{
return L->Next ==NULL;
}
void Delete(int X, struct passenger* L)
{
if(!isEmpty(L))
{
struct passenger* P;
struct passenger* temp;
P = FindPrevious(X, L);
if(P!= NULL)
{
temp = P->Next;
P->Next = temp->Next; //bypass delete cell
free(temp);
}
}
}
struct passenger* MakeEmpty(struct passenger* L)
{
L = ( struct passenger *)malloc(sizeof(struct passenger));
if(L == NULL)
printf ("Out of memory!\n");
else
L->Next = NULL;
return L;
}
void Load_bus_information()
{
FILE* file;
char chB;
char Bname[20];
// Opening file in reading mode
file = fopen("busses.txt", "r");
if (NULL == file)
{
("file can't be opened \n");
}
char Bbuf[100] ;
char Btemp[150];
char timeB[145] ;
char Bdestination[150] ;
char Bsource[150] ;
int bus_num, dateB, cap, pr ;
int counter =0;
while (fgets(Bbuf,100,file))
{
bus_num = atoi( strcpy(Btemp,strtok(Bbuf,"#")));
dateB= atoi( strcpy(Btemp,strtok(NULL,"#")));
strcpy(timeB,strtok(NULL,"#"));
strcpy(Bsource,strtok(NULL,"#"));
strcpy(Bdestination,strtok(NULL,"#"));
pr= atoi( strcpy(Btemp,strtok(NULL,"#")));
cap= atoi( strcpy(Btemp,strtok(NULL,"#")));
for(int s=0; s<5; s++)
{
price[s]= pr;
}
for(int s=0; s<5; s++)
{
capacity[s]= cap;
}
for(int s=0; s<5; s++)
{
bus_number[s]= bus_num;
}
for(int s=0; s<150; s++)
{
bus_date[s]= dateB;
}
for(int s=0; s<150; s++)
{
bus_time[counter][s]= timeB[s];
}
for(int s=0; s<150; s++)
{
sourceBus_all[counter][s]= Bsource[s];
}
for(int s=0; s<150; s++)
{
destinationBus_all[counter][s]= Bdestination[s];
}
counter++;
printf("%-10d %-10d %-10s %-15s %-15s %-15d %-15d \n",bus_num, dateB, timeB, Bsource, Bdestination, pr, cap );
}
}
void Load_pass_information()
{
FILE* fout;
char ch;
char fname[20];
// Opening file in reading mode
fout = fopen("passengers.txt", "r");
if (NULL == fout)
{
printf("file can't be opened \n");
}
// Printing what is written in file
char buf[100] ;
char temp[150];
char source[150] ;
char destination[150] ;
char time[150] ;
int date ;
int id ;
int count =0;
// cutting each line in the file and store them in variables
while (fgets(buf,100,fout))
{
id = atoi( strcpy(temp,strtok(buf,"#")));
date= atoi( strcpy(temp,strtok(NULL,"#")));
strcpy(time,strtok(NULL,"#"));
strcpy(source,strtok(NULL,"#"));
strcpy(destination,strtok(NULL,"#"));
//****************
struct passenger * head;
insert(id, date, time, source, destination, L );
}
count++;
fclose(fout);
}
int Assign_passengers_print_buss_information()
{
//passenger * buss_array[100];
}
int Print_specific_bus_info()
{
}
int Print_unmatched_passengers()
{
}
int Add_new_passenger()
{
int add_id, add_date;
char add_time[100],add_source [100], add_destination [100];
printf("please enter the id of the passenger:_");
scanf("%d", &add_id);
printf("please enter the date :_");
scanf("%d", &add_date);
printf("please enter the time:_");
// for (int i = 0;i < 4;i++)
scanf("%s", add_time);
printf("please enter the place to be collected :_");
scanf("%s", add_source);
printf("please enter the destination:_");
scanf("%s", add_destination);
printf("\n");
Load_pass_information();
insert(add_id, add_date, add_time, add_source, add_destination, L );
//Load_pass_information();
printf("\n");
}
void Delete_passenger( )
{
int X;
printf("enter id of the passenger that will be deleted ");
scanf("%d", &X);
Delete( X,L);
Load_pass_information();
}
int Delete_bus_number()
{
struct passenger*L;
PrintList(L);
}
void PrintList( struct passenger *L)
{
struct passenger* P = L;
if( isEmpty(L))
printf("Empty list\n");
else
do
{
P=P->Next;
printf(" %-10d %-10d %-10s %-10s %-10s \n",P->id_p, P->date_p, P->time_p,P->sour_p,P->des_p);
}
while( !IsLast(P, L) );
printf("\n");
}
this is the whole code so you can copy&paste it if you want, now if you press 8 it should not delete, I made it so it tells if the list is empty or not, which in my case it tells me the list is empty when it shouldn't be.
now load_pass is the function that's responsible to read from the file (read a line and pars it) the insert function should take care of the nodes
the data that would be included in the file:
1970111231#12:51#12072015#London#Liverpool
1251222415#01:12#16012015#California#Florida
1255122451#00:15#12052019#Chicago#Arizona
just to clarify when pressing 8 it should print the parsed data, i.e: 1970111231 12:51 12072015 London Liverpool

Sort two lists that started from a single linked list?

EDIT: This question has not received any feedback in a few days and I would like to ask if there are any unclear parts that I could improve in the description so you could attempt answering without hesitation. Thank you.
The program given below, groups the input in two different tables based on the gender and should sort the data by age in descending order. See below for more explanation:
Insert the code of the person Number 1: 1
Insert the age of the person Number 1: 1
Insert the gender of the person Number 1: 1
Insert the code of the person Number 2: 2
Insert the age of the person Number 2: 2
Insert the gender of the person Number 2: 1
Insert the code of the person Number 3: 3
Insert the age of the person Number 3: 3
Insert the gender of the person Number 3: 1
Insert the code of the person Number 4: 4
Insert the age of the person Number 4: 2
Insert the gender of the person Number 4: 0
Insert the code of the person Number 5: 5
Insert the age of the person Number 5: 3
Insert the gender of the person Number 5: 0
And the result is the following:
Men
Code Age Gender
3 3 1
1 1 1
2 2 1
Women
Code Age Gender
4 2 0
5 3 0
The proper result should be the following (hint: Sorted by Age):
Men
Code Age Gender
3 3 1
2 2 1
1 1 1
Women
Code Age Gender
5 3 0
4 2 0
-NOTES-
The issue is probably only in the sort_List() function and it is needed to include the first node of two lists in a sorting function.
How can the sortList() be modified to work correctly?
The code is displayed below:
#include <stdio.h>
#include <stdlib.h>
typedef struct people
{ /* a struct for people*/
int code; /* a unique identifier for each person*/
int age;
int gender;
struct people *next;
} ppl;
ppl *make_ppl(int code, int age, int gender, ppl *next)
{
ppl *p = malloc( sizeof(struct people) ); //as suggested in the comments
p->code = code;
p->age = age;
p->gender = gender;
p->next = next;
return p;
}
// a function to insert nodes
void insertFirst(ppl **ppHead, int code, int age, int gender)
{
*ppHead = make_ppl(code, age, gender, *ppHead);
}
void sortList() {
//Node current will point to head
int head;
ppl *current = head, *index = NULL;
int temp;
if(head == NULL) {
return;
}
else {
while(current != NULL) {
//Node index will point to node next to current
index = current->next;
while(index != NULL) {
//If current node's data is greater than index's node data, swap the data between them
if(current->age < index->age) {
temp = current-> age;
current->age = index->age;
index->age = temp;
temp = current-> code;
current->code = index->code;
index->code = temp;
temp = current-> gender;
current->gender = index->gender;
index->gender = temp;
}
index = index->next;
}
current = current->next;
}
}
}
// display the list
void printList(const char *title, ppl const *head)
{
sortList();
static const char *myStrings[] = {"Code", "Age", "Gender"};
static const size_t n_strings = sizeof myStrings / sizeof *myStrings;
int i;
puts(title);
for (i=0; i<n_strings; ++i)
printf("\t%s", myStrings[i]);
fputc('\n', stdout);
// start from the beginning
while (head != NULL)
{
printf("\t%d\t%d\t%d\n", head->code, head->age, head->gender);
head = head->next;
}
}
and then the main() is below:
int main()
{
int i;
ppl *z1 = NULL;
ppl *z2 = NULL;
int code1, age1, gender1;
for (i = 1; i <= 3; i++)
{
printf("Insert the code of the person Number %d: ", i);
scanf("%d", &code1);
printf("Insert the age of the person Number %d: ", i);
scanf("%d", &age1);
printf("Insert the gender of the person Number %d: ", i);
scanf("%d", &gender1);
if (gender1 == 1)
insertFirst(&z1, code1, age1, gender1); // Here it stores in z1 for men
else
insertFirst(&z2, code1, age1, gender1); // Here it stores in z2 for women
}
printList("Men", z1);
printList("Women", z2);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
typedef struct people
{ /* a struct for people*/
int code; /* a unique identifier for each person*/
int age;
int gender;
struct people *next;
} ppl;
ppl *make_ppl(int code, int age, int gender, ppl *next)
{
ppl *p = malloc( sizeof(struct people) );;
p->code = code;
p->age = age;
p->gender = gender;
p->next = next;
return p;
}
// a function to insert nodes
void insertFirst(ppl **ppHead, int code, int age, int gender)
{
*ppHead = make_ppl(code, age, gender, *ppHead);
}
void sortList(ppl *head) {
//Node current will point to head
ppl *current = head, *index = NULL;
int temp;
if(head == NULL) {
return;
}
else {
while(current != NULL) {
//Node index will point to node next to current
index = current->next;
while(index != NULL) {
//If current node's data is greater than index's node data, swap the data between them
if(current->age < index->age) {
temp = current-> age;
current->age = index->age;
index->age = temp;
temp = current-> code;
current->code = index->code;
index->code = temp;
temp = current-> gender;
current->gender = index->gender;
index->gender = temp;
}
index = index->next;
}
current = current->next;
}
}
}
// display the list
void printList(const char *title, ppl *head)
{
static const char *myStrings[] = {"Code", "Age", "Gender"};
static const size_t n_strings = sizeof myStrings / sizeof *myStrings;
sortList(head);
int i;
puts(title);
for (i=0; i<n_strings; ++i)
printf("\t%s", myStrings[i]);
fputc('\n', stdout);
// start from the beginning
while (head != NULL)
{
printf("\t%d\t%d\t%d\n", head->code, head->age, head->gender);
head = head->next;
}
}
void deleteList(ppl **ppHead)
{
while (*ppHead)
{
ppl *p = *ppHead;
*ppHead = p->next;
free(p);
}
}
int main()
{
int i;
ppl *z1 = NULL;
ppl *z2 = NULL;
int code1, age1, gender1;
for (i = 1; i <= 6; i++)
{
printf("Insert the code of the person Number %d: ", i);
scanf("%d", &code1);
printf("Insert the age of the person Number %d: ", i);
scanf("%d", &age1);
printf("Insert the gender of the person Number %d: ", i);
scanf("%d", &gender1);
if (gender1 == 1)
insertFirst(&z1, code1, age1, gender1); // Here it stores in z1 for men
else
insertFirst(&z2, code1, age1, gender1); // Here it stores in z2 for women
}
printList("Men", z1);
printList("Women", z2);
return 0;
}

Something wrong with add func

When I print the linked list countryName value always stay with the last string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct usa_primaries * ptr;
typedef struct primariesDate{
int month;
int day;
int hour;
}primariesDate;
typedef struct usa_primaries{
primariesDate date;
char *countryName;
int isOpen;
ptr next;
}usa_primaries;
void add (int month, int day, int hour, char *country, int isOpen, ptr *head) {
ptr t;
t = (ptr) malloc(sizeof(usa_primaries));
t->date.month = month;
t->date.day = day;
t->date.hour = hour;
t->countryName = (char *) malloc(strlen(country)+1);
strcpy(t->countryName, country);
t->isOpen = isOpen;
if(!(*head)) {
t->next = NULL;
*head = t;
}
else {
t->next = *head;
*head = t;
}
Below is the main function, I'm trying to print only countryName details but what I see is only the last value that is inserted. for example: scanf: test1, test2 the output is: test2 test2
int main() {
ptr head = NULL;
int month, day, hour, isopen;
char country[20];
while (scanf("%d %d %d %s %d", &month, &day, &hour, country, &isopen) != EOF) {
add(month, day, hour, country, isopen, &head);
}
ptr print = head;
while (print) {
printf("\n %s ", head->countryName);
print = print->next;
}
free(head);
return 0;
}
while (print) {
printf("\n %s ", head->countryName);
// ^^^^
print = print->next;
}
You print only the head in the loop. You should print the current node:
while (print) {
printf("\n %s ", print->countryName);
// ^^^^^
print = print->next;
}

Adding struct pointer to a pointer array

I have a problem and I really dont know what to do.
I'am trying to insert "new students" to an student-array. The array contains pointers to the created structs. Can somebody find the error? It adds the student-structs to the array but especially the printing doesnt work.
It would be really helpful, if somebody could help me. :) PS: You can just copy the code.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student
{
unsigned int matnr;
char *name;
struct student *next_student;
} Student;
Student **hash_tabelle[MAX_HASH];
void insert_student (unsigned int matnr, char *name)
{
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(sizeof(*name)+1);
neuer_student->matnr = matnr;
strcpy(neuer_student->name, name);
neuer_student->next_student = NULL;
// Index im Hash-Array ermitteln
int hash_index = matnr % 10;
if(hash_tabelle[hash_index] == NULL)
{
neuer_student->next_student = hash_tabelle[hash_index];
hash_tabelle[hash_index] = neuer_student;
}
else
{
while(*hash_tabelle[hash_index] != NULL && (((*hash_tabelle[hash_index])->matnr - neuer_student->matnr) <= 0))
hash_tabelle[hash_index] = &(*hash_tabelle[hash_index])->next_student;
neuer_student->next_student = *hash_tabelle[hash_index];
*hash_tabelle[hash_index] = neuer_student;
}
}
void print_hash_tabelle()
{
for(int i = 0; i != MAX_HASH - 1; i++){
printf("%d)\t", i);
hash_tabelle[i] = &(*hash_tabelle[i])->next_student;
for(; hash_tabelle[i] != NULL; hash_tabelle[i] = &(*hash_tabelle[i])->next_student){
printf("%s (%d)", (&(*hash_tabelle[i])->name), (&(*hash_tabelle[i])->matnr));
}
printf("\t");
}
}
int main()
{
unsigned int matnr;
char name[100];
do
{
printf("Matrikelnummer:\t");
scanf("%d", &matnr);
fflush(stdin);
getchar(); // um das \n aus dem Puffer zu kriegen und rauszuschmeiƟen
printf("Name:\t\t");
fgets(name, 30, stdin);
insert_student(matnr, name);
}
while (matnr != 0);
print_hash_tabelle();
return 0;
}
Using a hash table is so simple... No need to use dereferencing for a fixed-size array of linked-list pointers.
Step 1 - a hash table is a array of linked-list pointers.
As #BLUEPIXY suggests:
Student *hash_tabelle[MAX_HASH];
Step 2 - to allocate and free each linked-list, initialize each item to NULL.
Otherwise, if(hash_tabelle[hash_index] == NULL) is Undefined
behavior in the function insert_student().
void hash_init()
{
for(int i=0;i<MAX_HASH;i++) {
hash_tabelle[MAX_HASH]=NULL;
}
}
Step 3 - allocate enough char to store the char *name to insert_student().
As # WhozCraig suggests, use strlen().
void insert_student (unsigned int matnr, char *name)
{
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(strlen(name)+1);
neuer_student->matnr = matnr;
strcpy(neuer_student->name, name);
neuer_student->next_student = NULL;
Step 4 - add the neuer_student in the hash_tabelle[] (function insert_student())
Warning: the index shall be included in the size of the array
[0..MAX_HASH[. (using 10 instead of MAX_HASH could become a bug).
int hash_index = matnr % MAX_HASH;
When the hash_tabelle[hash_index] is NULL, simple store the
neuer_student. No need to modify neuer_student->next_student.
if(hash_tabelle[hash_index] == NULL)
{
hash_tabelle[hash_index] = neuer_student;
}
Else explore the linked-list of hash_tabelle[hash_index] to store
the neuer_student at the end.
else
{
Student *tmp;
tmp = hash_tabelle[hash_index];
while (tmp->next_student!=NULL) {
tmp = tmp->next_student;
}
tmp->next_student = neuer_student;
}
Step 5 - to print the all items of the hash table (function print_hash_tabelle())
Reuse the same method to explore each linked-list pointer.
Warning: explore all item from 0 to MAX_HASH-1
void print_hash_tabelle()
{
for(int i = 0; i < MAX_HASH; i++){ // ERR != MAX_HASH - 1; i++){
printf("%d)\t", i);
Student *tmp = hash_tabelle[i];
while (tmp!=NULL) {
printf("%s (%d)", tmp->name, tmp->matnr);
tmp = tmp->next_student;
}
printf("\n");
}
}
Step 6 - free the memory of each item of the hash_tabelle[].
Free the allocated string free(tmp->name);.
Remove the current student hash_tabelle[i] = tmp->next_student;
Free the allocated student free(tmp);
Repeat until the end of the linked-list
That's all (no change in the main() except adding a call to hash_free() at the end).
void hash_free()
{
for(int i=0;i<MAX_HASH;i++) {
Student *tmp = hash_tabelle[i];
while (tmp!=NULL) {
free(tmp->name);
hash_tabelle[i] = tmp->next_student;
free(tmp);
tmp = hash_tabelle[i];
}
}
}
like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student {
unsigned int matnr;
char *name;
struct student *next_student;
} Student;
Student *hash_tabelle[MAX_HASH];
void insert_student (unsigned int matnr, char *name){
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(strlen(name)+1);
strcpy(neuer_student->name, name);
neuer_student->matnr = matnr;
//neuer_student->next_student = NULL;
int hash_index = matnr % MAX_HASH;
Student head = { .next_student = hash_tabelle[hash_index] };
Student *prev = &head, *curr = head.next_student;
while(curr != NULL && curr->matnr <= neuer_student->matnr){
prev = curr;
curr = curr->next_student;
}
neuer_student->next_student = curr;
prev->next_student = neuer_student;
hash_tabelle[hash_index] = head.next_student;
}
void print_hash_tabelle(void){
for(int i = 0; i < MAX_HASH; i++){
printf("%d)\t", i);
for(Student *p = hash_tabelle[i]; p; p = p->next_student){
printf("%s (%d)\t", p->name, p->matnr);
}
printf("\n");
}
}
void free_hash_tabelle(void){
for(int i = 0; i < MAX_HASH; i++){
Student *p = hash_tabelle[i];
while(p){
Student *temp = p->next_student;
free(p->name);
free(p);
p = temp;
}
}
}
int main(void){
int matnr = -1;//for %d of scanf
char name[100];
while(1){
printf("Matrikelnummer(-1 for end input): ");fflush(stdout);
scanf("%d", &matnr);
if(matnr < 0)
break;
while(getchar() != '\n');
printf("Name: ");fflush(stdout);
fgets(name, sizeof name, stdin);
name[strcspn(name, "\n")] = 0;
insert_student(matnr, name);
}
print_hash_tabelle();
free_hash_tabelle();
return 0;
}

Resources