I was asked to make a hash table program which input name and age. I declared name and age as char. While doing the search function, I need to print the name and the age but the age do not print. What is wrong with my code?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
int n;
int count;
struct data
{
char name [100];
char age[5];
struct data *next;
};
struct data *chain[100000];
struct data* insert(char name[], char age[]){
struct data *curr = (struct data*) malloc (sizeof(data));
strcpy(curr->name, name);
strcpy(curr->age, age);
curr->next = NULL;
return curr;
};
//hash function
int hashing(char name[]){
int first = name[0];
return first % n;
}
//buat tau di index ke x dia data ke brp
void add(struct data *newNode){
int hash = hashing(newNode->name);
printf("index->%d\n", hash);
if(chain[hash] == NULL){
chain[hash] = newNode;
}
else
{
struct data *temp = chain[hash];
while(temp->next != NULL){
temp = temp->next;
//count++;
}
count++;
temp->next = newNode;
//count++;
}
printf("data-> %d\n", count);
}
void view(){
for(int i = 0 ; i < n ; i ++)
{
int count = 0;
if(chain[i]!=NULL){
printf("=== index %d data ===\n", i );
struct data *temp = chain[i];
while(temp!=NULL){
printf("data %d\n", count);
printf("name=%s age=%s\n", temp->name, temp->age);
temp = temp->next;
count ++;
}
}
}
printf("\n");
}
void search(int hash){
char age[5];
char search[100];
printf("Search name:");
scanf(" %[^\n]s", search);
int key = hashing(search);
printf("Search data %s from index %d data....\n", search, key);
if(strcmp(chain[key]->name, search)==0){
printf("data found at node %d\n", key);
printf("name = %s age = %s\n", search, age);
}
else
{
struct data *temp = chain[key];
while(temp->next!=NULL){
if(strcmp(chain[key]->name, search)==0){
printf("data found at node %d\n", key);
printf("name = %s age = %s\n", search, age);
}
temp = temp->next;
}
if(strcmp(temp->name, search)==0 && temp->next==NULL){
printf("data found at node %d\n", key);
printf("name = %s age = %s\n", search, age);
}
else{
printf("no data found!\n");
}
}
}
//void remove(int hash){
// //int key = item->key;
// int hash = hashing(key);
// int option;
// printf("input option:");
// scanf("%d", &option);
// char search[100];
// printf("delete name:");
// scanf(" %[^\n]s", search);
// int first = search[0];
// int key = first % n;
// printf("Search data %s from index %d data....\n", search, key);
// if(chain[key]==hash){
// chain[key]=-1;
// }
// else
// {
// printf("try");
// }
//}
int main(){
char name[100];
char age[5];
printf("input the number of hash table: ");
scanf("%d", &n); getchar();
struct data *chain[n];
int chainSize[n]={0};
printf("\n");
int option;
do{
printf("=== Option Menu ===\n");
printf("1. insert data\n");
printf("2. delete data\n");
printf("3. search data\n");
printf("4. view data\n");
printf("5. exit\n");
printf("input option: ");
scanf("%d", &option); getchar();
switch(option){
case 1:{
printf("input name: ");
scanf(" %[^\n]s", name);
printf("input age: ");
scanf(" %[^\n]s", age);
add(insert(name,age));
printf("\n");
break;
}
case 2:
{
//remove();
break;
}
case 3:
{
search(n);
break;
}
case 4:
{
view();
break;
}
}
}while(option!=5);
}
the output is like this
name = hansol
age =
when it is supposed to be like this:
name = hansol
age = 23
so the age variable does not print while doing the search function
Related
Here is my struct
struct Student
{
int numberofstudents;
float mid,prj,final,hmw;
int lettergrade;
int studentnumber;
char name[40];
char lastname[40];
int birthyear;
float totalgrade;
struct Student *next;
}* head;
And I have a function like this
void searchbylastname(char *lastname)
{
struct Student * temp = head;
while(temp!=NULL)
{
if(temp->lastname == lastname){
printf("Student Number: %d\n", temp->studentnumber);
printf("Name: %s\n", temp->name);
printf("Surname: %s\n", temp->lastname);
printf("Birth Year: %d\n", temp->birthyear);
printf("Total Grade: %0.2f\n", temp->totalgrade);
return;
}
temp = temp->next;
}
printf("Student with student number %s is not found !!!\n", lastname);
}
I'm calling it in main with switch case
head = NULL;
int choice;
char name[50];
char lastname[50];
int birthyear;
int studentnumber;
float totalgrade;
float prj,hmw,mid,final;
case 6:
printf("Enter student lastname to search: ");
scanf("%s", &lastname);
searchbylastname(lastname);
break;
but it cannot search by last name, it's automatically direct me here;
printf("Student with student number %s is not found !!!\n", lastname);
I don't know what to do, if anyone has an opinion, I would really appreciate it.
== does not compare strings in C only the references (addresses) of those strings. If they do not reference the same object they always will be different.
To compare strings you need to use strcmp function.
https://www.man7.org/linux/man-pages/man3/strncmp.3.html
You have more problems in your code. Even if you use strcmp it will display the message that the student has not been found. If you may have more students having the same surmane (which rather expected you need add a flag)
void searchbylastname(char *lastname)
{
struct Student * temp = head;
int studentsFound = 0;
while(temp!=NULL)
{
if(!strcmp(temp->lastname,lastname)){
stutentsFound = 1;
printf("Student Number: %d\n", temp->studentnumber);
printf("Name: %s\n", temp->name);
printf("Surname: %s\n", temp->lastname);
printf("Birth Year: %d\n", temp->birthyear);
printf("Total Grade: %0.2f\n", temp->totalgrade);
}
temp = temp->next;
}
if(!studentsFound)
printf("Students having %s surname have not been found !!!\n", lastname);
}
I'm writing this code to store data records of students' first name, last name, scores and zip codes. I have almost everything done but my Print() function doesn't print the first element of node 2(first name of 2nd student) and turns into an infinite loop when I input ore than 2 nodes, what am i doing wrong?
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
void Insert(char first[20], char last[20], float data, char zip[50]);
void delete(int e);
void Print();
double median();
struct node
{
char first_name[20];
char last_name[20];
float score;
char zip_code[50];
struct node *ptr;
};
int n;
struct node* head =NULL;
struct node* tail=NULL ;
void Insert(char first[20], char last[20], float data, char zip[50])
{
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp->ptr=NULL;
strcpy(temp->first_name,first);
strcpy(temp->last_name,last);
temp->score=data;
strcpy(temp->zip_code,zip);
if(head==NULL)
{
head=temp;
tail=temp;
return;
}
tail->ptr=temp;
tail=temp;
free(temp);
temp=NULL;
}
void delete(int e)
{
int i;
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
if(e==1)
{
head=temp->ptr;
free(temp);
return;
}
else if(e==n)
{
while(temp->ptr->ptr!=NULL)
{
temp=temp->ptr;
}
temp->ptr=NULL;
free(temp->ptr);
return;
}
for(i=0; i<(e-2); ++i)
temp=temp->ptr;
struct node *temp1=temp->ptr;
temp->ptr=temp1->ptr;
free(temp1);
}
void Print()
{
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
printf("Data entered is below: \n");
while(temp!=NULL)
{
printf("First Name: %s, Last Name: %s, Score: %.2f, Zip Code: %s",temp->first_name,temp->last_name,temp->score,temp->zip_code);
temp=temp->ptr;
printf("\n");
}
printf("\n\n\n");
}
double median()
{
double median,tmp;;
double *ex=(double*)malloc(sizeof(double));/*head*/
double *exe=(double*)malloc(sizeof(double));/*dynamic*/
ex=exe;
int i=1,term,j;
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
while(i<=n)
{
temp->ptr;
*exe=temp->score;
exe++;
}
for(i=0; i<n; i++)
{
for(j=i+1; j<n; j++)
{
if( *(ex+i) > *(ex+j))
{
tmp = *(ex+i);
*(ex+i) = *(ex+j);
*(ex+j) = tmp;
}
}
}
if(n%2==0)
{
/*even;median=n/2-1*/
term=(n/2)-1;
median= (*(ex+(term-1)));
return median;
}
/*odd; median=n-1/2*/
term=(n-1)/2;
median= (*(ex+(term-1)));
return median;
}
int main()
{
char name1[20],name2[20], code[50];
float x;
int i,option,index;
printf("Enter the number of nodes: ");
scanf("%d",&n);
printf("Please enter the records of students in the following format(click enter for new students)\n");
printf("First_Name Last_Name Score Zip_Code\n");
for(i=1; i<=n; ++i)
{
scanf(" %s",name1);
scanf(" %s",name2);
scanf(" %f",&x);
scanf(" %s",code);
Insert(name1,name2,x,code);
}
printf("\n");
while(1)
{
printf("Choose one of the following options: \n");
printf("Print records (press 1)\nAdd a new record (press 2)\nDelete record(s) (press 3)\nSearch by zip code (press 4)\nSearch by score range (press 5)\nFind median score (press 6)\nExit the program (press 0)\n");
scanf("%d",&option);
switch(option)
{
case 0:
{
/*Exit Program*/
exit(0);
break;
}
case 1:
{
/*print*/
Print();
break;
}
case 2:
{
/*insert*/
getchar();
printf("Enter the new record in the following format: \nFirst_Name Last_Name Score Zip_Code\n");
scanf("%s",name1);
scanf("%s",name2);
scanf("%f",&x);
scanf("%s",code);
getchar();
Insert(name1,name2,x,code);
break;
}
case 3:
{
/*delete*/
printf("Enter the node/record to be deleted: ");
scanf("%d",&index);
delete(index);
printf("The deletion of record %d has been succesfully completed!\n\n",index);
break;
}
case 4:
{
/*search by zip*/
break;
}
case 5:
{
/*search by score*/
break;
}
case 6:
{
/*find median*/
printf("Median score for the entered records is: %f",median());
break;
}
}/*switch*/
}/*while*/
return 0;
}
The Insert function is holding a reference to freed data:
tail=temp;
free(temp);
Attempting to use the storage referenced by tail after it's been freed is an error.
So this program is supposed to create a linked list for a car with the information of the year, Safety Rating, and Model. However when outputting the safety rating, say if the user enters "5", the program outputs it as some very large number that isn't what the user entered.
Example: If the user enters
Enter Year for Car: 1992
Enter Rating for Car (0.00 - 100.00): 25.5
Enter Model for Car: Chevy
The program output is...
The Cars in the List Are As Follows:
Year:1992 Rating:79960111893652368676401906121179136.00 Model:Chevy
When it should be....
The Cars in the List Are As Follows:
Year:1992 Rating:25.50 Model:Chevy
What am I doing wrong? Here is my full code...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 400
struct car {
int year;
float safeRating;
char model[MAXSIZE];
struct car *next;
};
typedef struct car Car;
typedef struct car *CarPtr;
void menu();
void printList(CarPtr);
CarPtr makeCar(int, float, char *);
CarPtr removeCar(CarPtr, int);
CarPtr addCar(CarPtr sPtr, int infoA, float infoB, char *infoC);
void viewCar(CarPtr sPtr, int infoA, float infoB, char *infoC);
int main()
{
CarPtr startPtr;
int infoA, choice;
float infoB;
char infoC;
startPtr = NULL;
menu();
scanf("%d", &choice);
while (choice != 5){
switch (choice){
case 1: printf("\nEnter Year for Car: ");
scanf("%d", &infoA);
printf("\nEnter Rating for Car (0.00 - 100.00): ");
scanf("%f", &infoB);
printf("\nEnter Model for Car: ");
scanf("%s", &infoC);
startPtr = addCar(startPtr, infoA, infoB, &infoC);
printList(startPtr);
printf("\n");
break;
case 2: printf("\nEnter Car for deletion : ");
scanf("%d", &infoA);
startPtr = removeCar(startPtr, infoA);
printList(startPtr);
printf("\n");
break;
case 3: printf("\nEnter Car Number to View : ");
scanf("%d", &infoA);
viewCar(startPtr, infoA, infoB, &infoC);
printf("\n");
break;
case 4: printList(startPtr);
printf("\n");
break;
default: printf ("Invalid Option... Please Try Again \n");
break;
}
menu();
scanf("%d", &choice);
}
return 0;
}
void menu()
{
printf ("\t1: Insert Car into Ordered List\n");
printf ("\t2: Remove Car from List\n");
printf ("\t3: View Car from List\n");
printf ("\t4: Printing the List\n");
printf ("\t5: Exit\n");
printf ("\tEnter Choice: ");
}
CarPtr makeCar(int infoA, float infoB, char *infoC)
{
CarPtr np = (CarPtr) malloc(sizeof(Car));
np->year = infoA;
np->safeRating = infoB;
strcpy(np->model, infoC);
np->next = NULL;
return np;
}
void printList(CarPtr sPtr)
{
if(sPtr == NULL){
printf ("\nThere are no Cars to be Printed\n");
}
else {
printf("The Cars in the List Are As Follows Sorted by Year: \n");
while (sPtr != NULL) {
printf("Year:%d Rating:%.2f Model:%s\n", sPtr->year, sPtr->safeRating, sPtr->model);
sPtr = sPtr->next;
}
}
}
CarPtr addCar(CarPtr sPtr, int infoA, float infoB, char *infoC)
{
CarPtr newPtr, currPtr, prevPtr;
newPtr = makeCar(infoA, infoB, infoC);
prevPtr = NULL;
currPtr = sPtr;
while (currPtr != NULL && infoA > currPtr->year) {
prevPtr = currPtr;
currPtr = currPtr->next;
}
if (prevPtr == NULL) { // inserting at the start of the list
newPtr->next = sPtr;
sPtr = newPtr; // start of list has now changed
}
else {
newPtr->next = currPtr;
prevPtr->next = newPtr;
}
return sPtr;
}
CarPtr removeCar(CarPtr sPtr, int infoA)
{
CarPtr previousPtr, currentPtr, tempPtr;
previousPtr = NULL;
currentPtr = sPtr;
if(sPtr == NULL){
printf ("\nThe List is empty... No cars to be Removed\n");
return sPtr;
}
while (currentPtr != NULL && currentPtr->year != infoA) {
previousPtr = currentPtr;
currentPtr = currentPtr->next;
}
if(currentPtr == NULL){
printf("\nCar ( %d ) was not found \n", infoA);
}
else if (previousPtr == NULL){ // if node to be deleted is the first node
tempPtr = sPtr;
sPtr = sPtr->next; // start of list has been changed
printf("\nCar ( %d ) was deleted \n", tempPtr->year);
free(tempPtr);
}
else{
tempPtr = currentPtr;
previousPtr->next = currentPtr->next;
printf("\nCar ( %d ) was deleted \n", tempPtr->year);
free(tempPtr);
}
return sPtr;
}
void viewCar(CarPtr sPtr, int infoA, float infoB, char *infoC)
{
CarPtr previousPtr, currentPtr;
previousPtr = NULL;
currentPtr = sPtr;
int position = 0;
if(sPtr == NULL){
printf ("\nThe List is empty... No cars to View\n");
return;
}
while (currentPtr != NULL && currentPtr->year != infoA) {
previousPtr = currentPtr;
currentPtr = currentPtr->next;
position++;
}
if(currentPtr == NULL){
printf("\nCar ( %d ) was not found \n", infoA);
}
else{
printf("\nCar ( %d ) Rating: %.2f Model: %s was found at position : %d\n", currentPtr->year, currentPtr->safeRating, currentPtr->model, (position + 1));
}
}
You're not allocating any space for the car model string. You're scanf("%s", &infoC);, but infoC is a single char, there's no space for a string. That's overwriting something and probably mucking with things. Then you go strcpy when you make your car, that will copy until it hits a NULL byte. ,, etc, etc, ,, UB. Best to define it as char infoC[MAXSIZE] to match what you have in struct car.
I am trying to create a print function for my linked list program.
Here is my code so far, the only printing I managed to do is within my readfile function. I have no idea how to use a function to print linked list elements.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct record { // to contain several data types
char process;
char state;
int NUT;
int AT;
int Prio;
struct reord *next;
};
typedef struct record node;
void readfile(node *newlist, node *ncurr, node *next, int quanta, int readincrement, int newincrement, int procnumb, char *fn);
node *crtnode();
main() {
int menu = 0, quanta, readincrement, newincrement, procnumb;
char fn[100];
node *newlist = NULL;
node *ncurr = NULL;
node *next =NULL;
char process, state;
int NUT, AT, Prio;
do {
printf("Selfish RR Algorathim\n");
printf("Enter 1 for existing file\n");
printf("Enter 2 for manual input\n");
printf("Enter 3 for random\n");
printf("Enter 4 for exit\n");
scanf("%d", &menu);
switch (menu) {
case 1:
printf("insert file name");
scanf("%s", &fn);
readfile(newlist, ncurr, next, quanta, readincrement, newincrement, procnumb, fn);
break;
case 2:
printf("boo");
break;
case 3:
printf("haha");
break;
default:
printf("Wrong choice again");
break;
}
} while (menu != 4);
}
void readfile(node *newlist, node *ncurr, node *next, int quanta, int readincrement, int newincrement, int procnumb, char *fn) {
FILE *myFile;
int t;
int j, i;
newlist = NULL;
myFile = fopen(fn, "r");
// reading the values that will be final through out this process
fscanf(myFile, "%d", &quanta);
fscanf(myFile, "%d", &newincrement);
fscanf(myFile, "%d", &readincrement);
fscanf(myFile, "%d", &procnumb);
printf("quanta = %d newinc = %d Readyinc = %d procnumb = %d \n", quanta, newincrement, readincrement, procnumb);
newlist = crtnode(); // creating memory locations for the new list
ncurr = newlist;
for (i = 0; i < procnumb; i++) {
ncurr->process = 'A' + i;
ncurr->state = '-';
fscanf(myFile, "%d", &ncurr->NUT);
fscanf(myFile, "%d", &ncurr->AT);
ncurr->Prio = '\0';
if (i <= procnumb - 1) {
ncurr->next = crtnode();
ncurr = ncurr->next;
}
}
ncurr = newlist;
for (i = 0; i < procnumb; i++) {
printf("\nnode = %p proc = %c state = %c NUT = %d AT = %d priority = %d nextnode = %p\n", ncurr, ncurr->process, ncurr->state, ncurr->NUT, ncurr->AT, ncurr->Prio, ncurr->next);
ncurr = ncurr->next;
}
fclose(myFile);
}
node *crtnode() {
return((node *)malloc(sizeof(node)));
}
I am coding for a simple linked list , but facing a little problem. The program is like it is accepting name, age and DOB through user, and memory for it is dynamically allocated. After taking data from the user, it is searching a name, asked by user, if the name exists, it should print all the details related to it.
Here is my code-
//function declarations
struct node *initnode(char *, char *, char *);
void add(struct node *);
struct node *printnode(struct node *);
struct node *searchname(struct node *, char *);
struct node {
char name[25];
char age[10];
char dob[10];
struct node *next;
};
struct node *head = (struct node *) NULL;
struct node *initnode(char *name, char *age, char *dob1)
{
struct node *ptr;
ptr = (struct node *) malloc(sizeof(struct node));
if (ptr == NULL)
return (struct node *) NULL;
else {
strcpy(ptr->name, name);
strcpy(ptr->age, age);
strcpy(ptr->dob, dob1);
ptr->next = NULL;
return ptr;
}
}
struct node *printnode(struct node *ptr)
{
printf("Name -> %s\n", ptr->name);
printf("age -> %s \n", ptr->age);
printf("dob ->%s\n", ptr->dob);
return ptr;
}
void add(struct node *newp)
{
struct node *temp = (struct node *) malloc(sizeof(struct node));
if (head == NULL)
head = newp;
else {
for (temp = head; temp->next != NULL; temp = temp->next);
temp->next = newp;
temp = newp;
}
free(temp);
}
struct node *searchname(struct node *ptr, char *name1)
{
if (strcmp(name1, ptr->name) == 0) {
printf("\n name found \n");
printf("\n details are -\n");
printnode(ptr);
return ptr;
} else {
printf("\n name not found in the database \n");
}
}
int main()
{
char name[25];
char name1[25];
char rep;
char age[10];
char dob[10];
int i;
int flag = 1;
struct node *ptr;
do {
fflush(stdin);
while (flag != 0) {
printf("Enter name -- ");
gets(name);
for (i = 0; name[i] != '\0'; i++)
if (isdigit(name[i])) {
printf("Error in user input, name should be in alphabets\n");
flag = 1;
break;
}
else
flag = 0;
}
flag = 1;
while (flag != 0) {
printf("Enter age -- ");
scanf("%s", &age);
fflush(stdin);
for (i = 0; age[i] != '\0'; i++)
if (isalpha(age[i])) {
printf("Error in user input, age should be in numbers\n");
flag = 1;
break;
} else {
flag = 0;
}
}
flag = 1;
while (flag != 0) {
printf("Enter dob in DD/MM/YY format-- ");
scanf("%s", &dob);
fflush(stdin);
for (i = 0; dob[i] != '\0'; i++) {
if (isalpha(dob[i])) {
printf("Error in user input, dob should be in numbers\n");
flag = 1;
break;
} else
flag = 0;
}
}
flag = 1;
ptr = initnode(name, age, dob);
add(ptr);
printf("\n Do you want to continue?<Y/N>:\n ");
scanf("%s", &rep);
//rep = getchar();
}
while (rep == 'Y' || rep == 'y');
printf("\n do u want to search for a name in the database? <Y/N>:\n");
scanf("%s", &rep);
if (rep == 'Y' || rep == 'y') {
printf("Enter name you want to search-- ");
scanf("%s", &name1);
ptr = searchname(head, name1);
} else {
printf("\n goodbye \n");
}
do {
printf("\n do u want to search again? <Y/N>:\n");
scanf("%s", &rep);
if (rep == 'Y' || rep == 'y') {
printf("Enter name you want to search-- ");
scanf("%s", &name1);
ptr = searchname(head, name1);
} else {
printf("\n goodbye \n");
}
}
while (rep == 'Y' || rep == 'y');
return 0;
}
The issue is that it is searching for the first entry only and not others, can anyone help me to sort out this? I am compiling through "gcc".
At a first glance, your search function is only comparing one element, the head of the list.
After comparing one element you must go to the next element. This can either be done recursively or with a while:
Recursive use:
struct node *searchname(struct node *ptr, char *name1)
{
if (ptr==NULL) //Reached end of the list
{
printf("\n name not found in the database \n");
return NULL;
}
if (strcmp(name1, ptr->name) == 0) { //found the element
printf("\n name found \n");
printf("\n details are -\n");
printnode(ptr);
return ptr;
} else { //search next element
return searchname(ptr->next,name1); //this will call your function again for the next element on the list
}
}
While use:
struct node *searchname(struct node *ptr, char *name1)
{
struct node *aux; // usually i use an auxiliary pointer in order to avoid unwanted overwrite at my pointer.
aux = ptr;
while (aux!=NULL)
{
if (strcmp(name1, aux->name) == 0) { //found the element
printf("\n name found \n");
printf("\n details are -\n");
printnode(aux);
return aux;
}
else { //move pointer to next element
aux=aux->next;
}
}
//if it reaches this point, the element was not found
printf("\n name not found in the database \n");
return NULL;
}
Check your add function, it is wrong. Step mentally through it, and see what happens
to your pointer, and to the memory it points to.
What are the malloc and free used for in the add function?