I would like to load the data back into the linked list after i terminate the program and run it the second time. But the previous list of data doesn't store back into the linked list the second time i run
insert with singly linked list:
tick *addinfo(tick *previous,char* serial,char* ticketno,char* name,char* id)
{
tick *info = malloc(sizeof(tick));
info->nextPtr = NULL;
info->visitor.SrNo =strdup(serial);
info->visitor.ticketNo = strdup(ticketno);
info->visitor.Name = strdup(name);
info->visitor.ID= strdup(id);
if (previous != NULL)
{
previous->nextPtr = info;
}
printf("visitor info has been added: %s %s %s %s",info->visitor.SrNo,info->visitor.ticketNo,info->visitor.Name,info->visitor.ID);
ptroutfile=fopen("output.txt","a");
fprintf(ptroutfile,"visitor info has been added: %s %s %s %s\n\n",info->visitor.SrNo,info->visitor.ticketNo,info->visitor.Name,info->visitor.ID);
fclose(ptroutfile);
return info;
}
readfile function:
void readfile(tick* startPtr)
{
FILE* cfptr=NULL;
char srno[20],ticketNo[20],name[30],id[20];
cfptr=fopen("ticket.txt","r");
while(fscanf(cfptr,"%s %s %s %s",srno,ticketNo,name,id) == 4)
{
tick *info = malloc(sizeof(tick));
info->nextPtr = NULL;
info->visitor.SrNo =strdup(srno);
info->visitor.ticketNo = strdup(ticketNo);
info->visitor.Name = strdup(name);
info->visitor.ID= strdup(id);
if (startPtr != NULL)
{
startPtr->nextPtr = info;
}
}
fclose(cfptr);
}
Calling the function in main:
int main ()
{
tick *visitorinfo = NULL;
tick *new = NULL;
readfile(visitorinfo);
}
Related
I made a program which reads input form a text file and create a linked list but have trouble doing it. I am still a beginner. The problem is the head pointer keeps moving when adding a new item.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <stdbool.h>
//Visitor information
struct visitData
{
char *SrNo;
char *ticketNo;
char *Name;
char *ID;
};
//Ticket linked list
struct ticket
{
struct visitData visitor;
struct ticket *nextPtr;
};
int main() { //main
FILE *fPtr = NULL;
fPtr = fopen("Tickets.txt", "a+");
if (fPtr == NULL)
{
printf("Error, please try again.\n");
return 0;
}
FILE *outfPtr = NULL;
outfPtr = fopen("output.txt", "w");
if (outfPtr == NULL)
{
puts("Error, could not create output file, please try again.");
return 0;
}
else {
struct ticket *head = NULL;
struct ticket *new = NULL;
struct visitData *nextPtr = NULL;
char sr[2];
char ticketNumber[20];
char name[30];
char id[24];
rewind(fPtr);
if (fscanf(fPtr, "%2s%20s%29s%24s", sr, ticketNumber, name, id) == 4)
{
new = malloc(sizeof(struct ticket));
new->visitor.SrNo = strdup(sr);
new->visitor.ticketNo = strdup(ticketNumber);
new->visitor.Name = strdup(name);
new->visitor.ID = strdup(id);
new->nextPtr = NULL;
head = new;
printf("%s\n", head->visitor.SrNo);
while (!feof(fPtr))
{
if (fscanf(fPtr, "%2s%20s%29s%24s", sr, ticketNumber, name, id) == 4)
new->visitor.SrNo = sr;
new->visitor.ticketNo = ticketNumber;
new->visitor.Name = name;
new->visitor.ID = id;
new->nextPtr = malloc(sizeof(struct ticket));
new = new->nextPtr;
new->nextPtr = NULL;
}
}
}
else
{
printf("%d",fscanf(fPtr, "%2s%20s%29s%24s", sr, ticketNumber, name, id));
new->visitor.SrNo = "0";
}
if (head == NULL)
{
printf("List is empty\n");
}
struct ticket *Ptr = NULL;
Ptr = head;
printf("%s\n", Ptr->visitor.SrNo);
while (Ptr != NULL)
{
printf("%s %s\n", Ptr->visitor.SrNo, Ptr->visitor.ticketNo);
Ptr = Ptr->nextPtr;
}
}
}
I did try to add a line which is `
new = malloc(sizeof(struct ticket));
`, but it became another problem, that the head pointer cannot link to the second node.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <stdbool.h>
//Visitor information
struct visitData
{
char *SrNo;
char *ticketNo;
char *Name;
char *ID;
};
//Ticket linked list
struct ticket
{
struct visitData visitor;
struct ticket *nextPtr;
};
int main() { //main
FILE *fPtr = NULL;
fPtr = fopen("Tickets.txt", "a+");
if (fPtr == NULL)
{
printf("Error, please try again.\n");
return 0;
}
FILE *outfPtr = NULL;
outfPtr = fopen("output.txt", "w");
if (outfPtr == NULL)
{
puts("Error, could not create output file, please try again.");
return 0;
}
else {
struct ticket *head = NULL;
struct ticket *new = NULL;
struct visitData *nextPtr = NULL;
char sr[2];
char ticketNumber[20];
char name[30];
char id[24];
rewind(fPtr);
if (fscanf(fPtr, "%2s%20s%29s%24s", sr, ticketNumber, name, id) == 4)
{
new = malloc(sizeof(struct ticket));
new->visitor.SrNo = strdup(sr);
new->visitor.ticketNo = strdup(ticketNumber);
new->visitor.Name = strdup(name);
new->visitor.ID = strdup(id);
new->nextPtr = NULL;
head = new;
printf("%s\n", head->visitor.SrNo);
while (!feof(fPtr))
{
if (fscanf(fPtr, "%2s%20s%29s%24s", sr, ticketNumber, name, id) == 4)
{
new = malloc(sizeof(struct ticket));
new->visitor.SrNo = sr;
new->visitor.ticketNo = ticketNumber;
new->visitor.Name = name;
new->visitor.ID = id;
new->nextPtr = malloc(sizeof(struct ticket));
new = new->nextPtr;
new->nextPtr = NULL;
}
}
}
else
{
printf("%d",fscanf(fPtr, "%2s%20s%29s%24s", sr, ticketNumber, name, id));
new->visitor.SrNo = "0";
}
if (head == NULL)
{
printf("List is empty\n");
}
struct ticket *Ptr = NULL;
Ptr = head;
printf("%s\n", Ptr->visitor.SrNo);
while (Ptr != NULL)
{
printf("%s %s\n", Ptr->visitor.SrNo, Ptr->visitor.ticketNo);
Ptr = Ptr->nextPtr;
}
}
}
typical way to add nodes to a list is:
new = malloc(size); // Create a new node
new->nextPtr = head; // Save the existing list
head = new; // Add the new element at the front of the list
You are changing head before saving your old value, so you lose the list.
I'm working on a client/server program where a client inputs name ,last name and phone number. The input functions works well. It adds to a linked list normaly. When I call search function with a phone number that is already in the linked list on the server it works perfectly but when I try to search for a phone number the server crashes stating Segmentation fault when it was supposed to just send to the client that the search was unsuccesful/wasnt found. This error only occurs when the linked list is not empty. If i search for a non existant number in empty list it responds like it should in the if statement.
I've tried so many options but I just dont see where it goes wrong.
Server
else if(strcmp(data_char_array,"output") == 0)
{
printf("[REQ] Client has requested a search\n");
return_value = read(client_info, izpis.phone_number, 100);
entry.phone_number[return_value] = 0;
if(ifExists(izpis.phone_number) == 1)
{
write(client_info, "none", 8);
printf("\n No match found!\n");
}
else
{
struct phonebook* find = findNum(izpis.phone_number);
char phone_num[101];
char last_n[31];
char first_n[31];
strncpy(phone_num, find->phone_number, 100);
strncpy(last_n, find->last_name, 30);
strncpy(first_n, find->first_name, 30);
write(client_info, "found",10);
write(client_info, first_n,100);
write(client_info, last_n,30);
write(client_info, phone_num, 30);
printf("\n Request processed succesfully\n");
}
struct phonebook* findNum(char phone[101]){
struct phonebook* curr = head;
if(head == NULL){
return NULL;
}
while(strcmp(curr->phone_number,phone))
{
if(curr->phone_number == NULL)
{
return NULL;
}
else
{
curr = curr->next;
}
}
return curr;
}
int ifExists(char phone[101]){
struct phonebook* curr = head;
if(head == NULL){
return 1;
}
while(strcmp(curr->phone_number,phone))
{
if(curr->phone_number == NULL)
{
return 1;
}
else
{
curr = curr->next;
}
}
return 0;
}
Client
char send[11] = "output";
char recieve[11];
char name[31];
char last[31];
char phone[101];
while(1)
{
return_value = write(data_socket, send, strlen(send));
if (return_value == -1)
{
perror("Error occurred while sending! Error at 0x1!");
exit(-1);
}
return_value = write(data_socket, argv[1], strlen(argv[1]));
if (return_value == -1)
{
perror("Error occurred while sending! Error at 0x2!");
exit(-1);
}
return_value = read(data_socket, recieve, 11);
recieve[return_value] = 0;
printf("Searching: %s\n", recieve);
if(strcmp(recieve, "found") == 0)
{
printf("Search was successful\n");
return_value = read(data_socket,name,31);
name[return_value] = 0;
printf("%s ", name);
return_value = read(data_socket,last,31);
last[return_value] = 0;
printf("%s ", last);
return_value = read(data_socket,phone,101);
phone[return_value] = 0;
printf("%s ", phone);
break;
findNum and ifExists are actually duplicates, same process but just return different structure. Would suggest to merge into findNum only.
struct phonebook* findNum(char phone[101]){
struct phonebook* curr = head;
if(head == NULL){
return NULL;
}
while(curr != NULL) {
if(curr->phone_number != NULL) {
if (strcmp(curr->phone_number, phone) == 0) {
return curr;
} //end if
} //end if
curr = curr->next;
}
return NULL;
}
Then, also need to change the function invocation
struct phonebook* find = findNum(izpis.phone_number);
if(find == NULL) {
write(client_info, "none", 8);
printf("\n No match found!\n");
}
else {
//struct phonebook* find = findNum(izpis.phone_number);
char phone_num[101];
char last_n[31];
char first_n[31];
strncpy(phone_num, find->phone_number, 100);
strncpy(last_n, find->last_name, 30);
strncpy(first_n, find->first_name, 30);
write(client_info, "found",10);
write(client_info, first_n,100);
write(client_info, last_n,30);
write(client_info, phone_num, 30);
printf("\n Request processed succesfully\n");
}
STUDENT *create_empty_list()
{
STUDENT *p_new_list;
if((p_new_list = (STUDENT*) malloc(sizeof(STUDENT))) == NULL)
{
printf("\nError #%d in create_empty_list.", HEADER_ALLOC_ERROR);
exit(HEADER_ALLOC_ERROR);
}
p_new_list->id_number = LIST_HEADER;
if((p_new_list->p_next_student = (STUDENT*) malloc(sizeof(STUDENT))) == NULL)
{
printf("\nError #%d in create_empty_list.", TRAILER_ALLOC_ERROR);
exit(TRAILER_ALLOC_ERROR);
}
p_new_list->p_next_student->p_next_student = LIST_TRAILER;
p_new_list->p_next_student->p_next_student = NULL;
return p_new_list;
}
I am not sure how to correctly attach the head and tail to the node.
I'm developing a client-server program and when and I'm trying to implement a user linked list using this structure:
typedef struct user {
char username[50];
int user_pid;
struct user *next;
} user_list;
I'm trying figure out what's wrong with the code, because the compiler doesn't give me any error, but when I try to user to print the users list, it simply doesn't display anything.
AddUser function:
AddUser(user_list *head, req req)
{
if(head == NULL)
{
head = malloc(sizeof(user_list));
if (head == NULL)
fprintf(stdout,"[SERVER] Error memory allocation ");
strcpy(head->username, req.str);
head->user_pid = req.client_pid;
head->next = NULL;
}
else
{
user_list *current = head;
while (current->next != NULL)
current = current->next;
current->next = malloc(sizeof(user_list));
strcpy(current->next->username, req.str);
current->next->user_pid = req.client_pid;
current->next->next = NULL;
}
num_users++;
}
Main Function (short version)
int Main()
{
struct request req;
struct answer ans;
user_list *head = NULL;
do{
read(fifo_1, &req, sizeof(req)); // Read client request
if(strcasecmp(req.str, "adduser") == 0)
{
AddUser(head, req);
strcpy(ans.str, "User added with success! You're logged!");
}
if(strcasecmp(req.str, "users") == 0) // Print on the screen the users list
{
user_list *current = head;
while (current != NULL)
{
fprintf(stdout, "%s\n", current->username);
fprintf(stdout, "%d\n", current->user_pid);
current = current->next;
}
}
}while(strcmp(req.str,"exit") != 0);
}
Putting together what others have already pointed out in comments:
Change main. Instead of
int Main()
use
int main()
The value of head, doesn't change in main when you change it in AddUser. Here's one solution. Return head from AddUser.
user_list* AddUser(user_list *head, req req)
{
if(head == NULL)
{
head = malloc(sizeof(user_list));
if (head == NULL)
fprintf(stdout,"[SERVER] Error memory allocation ");
strcpy(head->username, req.str);
head->user_pid = req.client_pid;
head->next = NULL;
}
else
{
user_list *current = head;
while (current->next != NULL)
current = current->next;
current->next = malloc(sizeof(user_list));
strcpy(current->next->username, req.str);
current->next->user_pid = req.client_pid;
current->next->next = NULL;
}
num_users++;
return head;
}
Capture the return value of AddUser in main. Instead of just
AddUser(head, req);
use
head = AddUser(head, req);
I have a linked list , which has full information
typdef struct details
{
struct details *head, *next, *curr;
char* values;
}
Details *fyllinfo ; //(this strcuct has full information)
/* fyllinfo this has been filled with many vallues*/
Now I need to copy the pointers to new list which can point only my required or matched data
Details *required;
char* myValue;
details *pstPtr =fyllinfo->head;
details *required = (details*) malloc(
sizeof(details));
required->head = required->next = NULL;
while(pstPtr != NULL)
{
if(NULL == pstPtr->values) goto NEXT;
printf("UUID FOUND IS [%s] and comapre with [%s] ",pstPtr->values,myvalue);
if(strCmp(pstPtr->values,myvalue)==0)
{
if(required->head == NULL)
{
required->head = required->curr = pstPtr;
}
else
{
required->next = pstPtr;
required->curr->next = pstPtr;
}
}
NEXT: pstPtr = pstPtr->next;
}
My Required ptr should have the pointer to only matched values
My code only points the first matched data and it has unmatched data in reuired->next pointer
This code works now... you just need to put some effort to understand it. you should be able to print the values. see how values are stored now.
details *pstPtr = fyllinfo;
details *required = NULL; //(details*)malloc(
details *head=NULL;
while (pstPtr != NULL)
{
if (1 == pstPtr->values)
printf("UUID FOUND IS [%d] and comapre with [%d] \n", pstPtr->values, 1);
if (pstPtr->values==1)
{
if (required == NULL)
{
required = (details*)malloc( sizeof(details));
head = required;
required->head = required->curr = pstPtr;
required->next = NULL;
}
else
{
required->next = (details*)malloc(sizeof(details));
required = required->next;
required->next = NULL;
required->curr = pstPtr;
}
}
pstPtr = pstPtr->next;
}
void display(struct details *r)
{
// r = fyllinfo;
if (r == NULL)
{
return;
}
while (r != NULL)
{
printf("%d ", r->curr->values);
r = r->next;
}
printf("\n");
}