My assignment was to read int input from two files. One contained a poem with misspelled words and the other contained a key with the misspelled word and the correct replacement right after.
I'm supposed to populate two linked lists with the information from each file and create a function that decodes the first file. I'm required to use pointers instead of char arrays in the linked list and at the end the program needs to print the first file with all corrections made.
I'm all good up until the decoder function needs to compare words with punctuation in them. How would i ignore punctuation without losing it in the final format.
Here's my decoder function:
LINK *decoder(TRANS *codet, LINK *head)
{
LINK *currentt;
currentt = head;
TRANS *current;
current = codet;
printf("Decoding...\n");
while (currentt != NULL)
{
current = codet;
while (1)
{
if ()
printf("Comparing %s with %s: \n", currentt->words, current->word1);
if (!strcmp(currentt->words, current->word1))
{
printf("Replacing...\n");
currentt->words = (char*)calloc(strlen(current->word2), sizeof(char));
strcpy(currentt->words, current->word2);
break;
}
current = current->next;
}
currentt = currentt->next;
}
return head;
}
Here's the rest of my code:
//Tristan Shepherd
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct node
{
char *words;
struct node *next;
};
struct codex
{
char *word1;
char *word2;
struct codex *next;
};
typedef struct node LINK;
typedef struct codex TRANS;
void printInsert(LINK *head)
{
printf("\n\nPrinting list: \n\n");
LINK *current;
current = head;
while (current != NULL) {
printf("%s ", current->words);
current = current->next;
}
}
void printCodex(TRANS *codet)
{
printf("\n\nPrinting code: \n\n");
TRANS *current;
current = codet;
while (current != NULL) {
printf("%s %s\n", current->word1, current->word2);
current = current->next;
}
}
void reverse(LINK **head)
{
struct node *prev = NULL;
struct node *current = *head;
struct node *next = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head = prev;
}
LINK *insertList(char *wordt, LINK *head)
{
LINK *current, *temp;
temp = (LINK *)malloc(sizeof(LINK));
temp->words = (char*)calloc(strlen(wordt)+1, sizeof(char));
strcpy(temp->words, wordt);
if (head == NULL)
{
head = (LINK *)malloc(sizeof(LINK));
head = temp;
temp->next = NULL;
return head;
}
current = head;
if (strcmp(current->words, wordt))
{
temp->next = current;
head = temp;
return head;
}
current = head;
while (current != NULL)
{
if (current->next == NULL || strcmp(current->next->words, wordt))
{
temp->next = current->next;
current->next = temp;
return head;
}
current = current->next;
}
}
TRANS *insertCodex(char *codeword, char *replace, TRANS *codet)
{
TRANS *current, *temp;
temp = (TRANS *)malloc(sizeof(TRANS));
temp->word1 = (char*)calloc(strlen(codeword)+1, sizeof(char));
temp->word2 = (char*)calloc(strlen(replace)+1, sizeof(char));
strcpy(temp->word1, codeword);
strcpy(temp->word2, replace);
if (codet == NULL)
{
codet = (TRANS *)malloc(sizeof(TRANS));
codet = temp;
temp->next = NULL;
return codet;
}
current = codet;
if (strcmp(current->word1, codeword) && strcmp(current->word2, replace))
{
temp->next = current;
codet = temp;
return codet;
}
current = codet;
while (current != NULL)
{
if (current->next == NULL || strcmp(current->next->word1, codeword) && strcmp(current->next->word2, replace))
{
temp->next = current->next;
current->next = temp;
return codet;
}
current = current->next;
}
}
TRANS *scanCodex(FILE *code, TRANS *codet)
{
char *codeword = (char*)malloc(13*sizeof(char));
char *replace = (char*)malloc(13*sizeof(char));
while(1)
{
fscanf(code, "%s %s", codeword, replace);
if (feof(code)) break;
codet = insertCodex(codeword, replace, codet);
}
fclose(code);
return codet;
}
LINK *scanInsert(FILE *stream, LINK *head)
{
char *input = (char*)malloc(13*sizeof(char));
while (1)
{
fscanf(stream, "%s", input);
if(feof(stream)) break;
head = insertList(input, head);
}
fclose(stream);
return head;
}
LINK *decoder(TRANS *codet, LINK *head)
{
LINK *currentt;
currentt = head;
TRANS *current;
current = codet;
printf("Decoding...\n");
while (currentt != NULL)
{
current = codet;
while (1)
{
if ()
printf("Comparing %s with %s: \n", currentt->words, current->word1);
if (!strcmp(currentt->words, current->word1))
{
printf("Replacing...\n");
currentt->words = (char*)calloc(strlen(current->word2), sizeof(char));
strcpy(currentt->words, current->word2);
break;
}
current = current->next;
}
currentt = currentt->next;
}
return head;
}
int main (void)
{
FILE *stream = fopen("hw10data.txt", "r");
FILE *code = fopen("hw10codex.txt", "r");
LINK *head;
TRANS *codet;
head = NULL;
codet = NULL;
head = scanInsert(stream, head);
reverse(&head);
printInsert(head);
codet = scanCodex(code, codet);
printCodex(codet);
head = decoder(codet, head);
printInsert(head);
exit(0);
}
#David C. Rankin
Contents of the Files:
File 1:
Eye I
eye I
chequer checker
Pea P
Sea C
plane plainly
lee skip
four for
revue review
Miss Mistakes
Steaks skip
knot not
sea see
quays keys
whirred word
weight wait
Two To
two to
Weather Whether
write right
oar or
aweigh away
threw through
Your You're
shore sure
two to
no know
Its It's
vary very
weigh way
tolled told
sew so
bless blessed
freeze frees
yew you
lodes loads
thyme time
right write
stiles styles
righting writing
aides aids
rime rhyme
frays phrase
come composed
posed skip
trussed trusted
too to
bee be
joule jewel
cheque check
sum some
File 2:
Eye have a spelling chequer,
It came with my Pea Sea.
It plane lee marks four my revue,
Miss Steaks I can knot sea.
Eye strike the quays and type a whirred,
And weight four it two say,
Weather eye am write oar wrong,
It tells me straight aweigh.
Eye ran this poem threw it,
Your shore real glad two no.
Its vary polished in its weigh.
My chequer tolled me sew.
A chequer is a bless thing,
It freeze yew lodes of thyme.
It helps me right all stiles of righting,
And aides me when eye rime.
Each frays come posed up on my screen,
Eye trussed too bee a joule.
The chequer pours over every word,
Two cheque sum spelling rule.
Here's my final code if you need it:
//Tristan Shepherd
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct node
{
char *words;
struct node *next;
};
struct codex
{
char *word1;
char *word2;
struct codex *next;
};
typedef struct node LINK;
typedef struct codex TRANS;
void delete(LINK **head, char *key)
{
LINK *temp = *head, *prev;
if (temp != NULL && !strcmp(temp->words, key))
{
*head = temp->next;
free(temp);
return;
}
while (temp != NULL && strcmp(temp->words, key))
{
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
free(temp);
}
void printInsert(LINK *head, int aftersort)
{
printf("\n\nPrinting list: \n\n");
LINK *current;
current = head;
while (current != NULL)
{
if (aftersort)
{
printf("%s", current->words);
}
else
{
printf("%s ", current->words);
}
current = current->next;
}
}
void printCodex(TRANS *codet)
{
printf("\n\nPrinting codex: \n\n");
TRANS *current;
current = codet;
while (current != NULL)
{
printf("%s %s\n", current->word1, current->word2);
current = current->next;
}
}
void reverse(LINK **head)
{
struct node *prev = NULL;
struct node *current = *head;
struct node *next = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head = prev;
}
LINK *insertList(char *wordt, LINK *head)
{
LINK *current, *temp;
temp = (LINK *)malloc(sizeof(LINK));
temp->words = (char*)calloc(strlen(wordt)+1, sizeof(char));
strcpy(temp->words, wordt);
if (head == NULL)
{
head = (LINK *)malloc(sizeof(LINK));
head = temp;
temp->next = NULL;
return head;
}
current = head;
if (strcmp(current->words, wordt))
{
temp->next = current;
head = temp;
return head;
}
current = head;
while (current != NULL)
{
if (current->next == NULL || strcmp(current->next->words, wordt))
{
temp->next = current->next;
current->next = temp;
return head;
}
current = current->next;
}
}
TRANS *insertCodex(char *codeword, char *replace, TRANS *codet)
{
TRANS *current, *temp;
temp = (TRANS *)malloc(sizeof(TRANS));
temp->word1 = (char*)calloc(strlen(codeword)+1, sizeof(char));
temp->word2 = (char*)calloc(strlen(replace)+1, sizeof(char));
strcpy(temp->word1, codeword);
strcpy(temp->word2, replace);
if (codet == NULL)
{
codet = (TRANS *)malloc(sizeof(TRANS));
codet = temp;
temp->next = NULL;
return codet;
}
current = codet;
if (strcmp(current->word1, codeword) && strcmp(current->word2, replace))
{
temp->next = current;
codet = temp;
return codet;
}
current = codet;
while (current != NULL)
{
if (current->next == NULL || strcmp(current->next->word1, codeword) && strcmp(current->next->word2, replace))
{
temp->next = current->next;
current->next = temp;
return codet;
}
current = current->next;
}
}
TRANS *scanCodex(FILE *code, TRANS *codet)
{
char *codeword = (char*)malloc(13*sizeof(char));
char *replace = (char*)malloc(13*sizeof(char));
while(1)
{
fscanf(code, "%s %s", codeword, replace);
if (feof(code)) break;
codet = insertCodex(codeword, replace, codet);
}
fclose(code);
return codet;
}
LINK *scanInsert(FILE *stream, LINK *head)
{
char *input = (char*)malloc(13*sizeof(char));
while (1)
{
fscanf(stream, "%s", input);
if(feof(stream)) break;
head = insertList(input, head);
}
fclose(stream);
return head;
}
LINK *decoder(TRANS *codet, LINK *head)
{
LINK *currentt;
currentt = head;
TRANS *current;
current = codet;
char *temp = (char*)malloc(33*sizeof(char));
while (currentt != NULL)
{
int CorP = 0;
int punct = 0;
int t = 0;
current = codet;
while (1)
{
if (!strcmp(currentt->words, current->word1))
{
currentt->words = (char*)calloc(strlen(current->word2)+1, sizeof(char));
strcpy(currentt->words, current->word2);
strcat(currentt->words, " ");
if (punct == 1)
{
strtok(currentt->words, " ");
strcat(currentt->words, ".\n");
}
if (punct == 2)
{
strtok(currentt->words, " ");
strcat(currentt->words, ",\n");
}
if (!strcmp(currentt->words, "skip "))
{
delete(&head, currentt->words);
}
break;
}
current = current->next;
if (current == NULL)
{
strcpy(temp, currentt->words);
if (!strcmp(currentt->words, strtok(temp, ".")))
{
if(!strcmp(currentt->words, strtok(temp, ",")))
{
if(t == 1)
{
strcat(currentt->words, " ");
if (punct == 1)
{
strtok(currentt->words, " ");
strcat(currentt->words, ".\n");
}
if (punct == 2)
{
strtok(currentt->words, " ");
strcat(currentt->words, ",\n");
}
break;
}
t++;
}
else
{
strcpy(currentt->words, strtok(currentt->words, ","));
current = codet;
punct = 2;
}
}
else
{
strcpy(currentt->words, strtok(currentt->words, "."));
current = codet;
punct = 1;
}
current = codet;
}
}
currentt = currentt->next;
}
return head;
}
int main (void)
{
FILE *stream = fopen("hw10data.txt", "r");
FILE *code = fopen("hw10codex.txt", "r");
LINK *head;
TRANS *codet;
head = NULL;
codet = NULL;
head = scanInsert(stream, head);
reverse(&head);
printInsert(head, 0);
codet = scanCodex(code, codet);
printCodex(codet);
head = decoder(codet, head);
printInsert(head, 1);
exit(0);
}
Related
Is it possible to have multiple data inside a single linked list node in C? And how do you input and access data with this?
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
char name[30];
struct node *next;
};
struct node *head, *tail = NULL;
void addNode(int data, char string) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = data;
newNode->name[30] = string;
newNode->next = NULL;
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void sortList() {
struct node *current = head, *index = NULL;
int temp;
if(head == NULL) {
return;
}
else {
while(current != NULL) {
index = current->next;
while(index != NULL) {
if(current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
struct node *current = head;
if(head == NULL) {
printf("List is empty \n");
return;
}
while(current != NULL) {
printf("%d - %s", current->data, current->name);
current = current->next;
}
printf("\n");
}
int main()
{
char string1[10] = "Aaron";
char string2[10] = "Baron";
char string3[10] = "Carla";
addNode(9, string1);
addNode(7, string2);
addNode(2, string3);
printf("Original list: \n");
display();
sortList();
printf("Sorted list: \n");
display();
return 0;
}
I don't understand why my code didn't work. I was trying to make use of single linked list where it can accept/input and print/output the number and the name at the same time.
What I want it to happen is to print the number and the name.
The output should be:
Carla - 2
Baron - 7
Aaron - 9
Please read my comments marked as // CHANGE HERE.
// CHANGE HERE: accept a character array as argument
void addNode(int data, char string[]) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = data;
// CHANGE HERE: copy char array argument to name
strncpy(newNode->name, string, 30);
newNode->next = NULL;
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void sortList() {
struct node *current = head, *index = NULL;
int temp;
char temp1[30];
if(head == NULL) {
return;
}
else {
while(current != NULL) {
index = current->next;
while(index != NULL) {
if(current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
// CHANGE HERE: swap the name along with data
strncpy(temp1, current->name, 30);
strncpy(current->name, index->name, 30);
strncpy(index->name, temp1, 30);
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
struct node *current = head;
if(head == NULL) {
printf("List is empty \n");
return;
}
while(current != NULL) {
printf("%d - %s\n", current->data, current->name);
current = current->next;
}
printf("\n");
}
I have a circular doubly linked list.
The deletefront() function is not working: the output is wrong. What is the mistake?
The other functions are working. But I get a wrong output after displaying after calling deletefront function. The 100 value which should be deleted is still appearing. Please correct it.
I have included the C source code:
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *rlink;
struct node *llink;
} node;
node *head = NULL;
node *getnode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
void insertfront(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
head->llink = newnode;
newnode->rlink = head;
head = newnode;
}
}
void insertend(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
node *temp = head;
do {
temp = temp->rlink;
} while (temp != head->llink);
newnode->rlink = temp->rlink;
temp->rlink = newnode;
newnode->llink = temp;
}
}
int lenlist() {
node *temp;
int count = 0;
temp = head;
do {
temp = temp->rlink;
count++;
} while (temp != head);
return count;
}
void insertatpos(int ele,int pos) {
if (pos == 1) {
insertfront(ele);
} else
if (pos == (lenlist() + 1)) {
insertend(ele);
} else
if (pos > 1 && pos <= (lenlist() + 1)) {
node *prev, *curr;
node *newnode = getnode(ele);
int count = 1;
curr = head;//curr points to 1st node
do {
prev = curr;
count++;
curr = curr->rlink;
if (count == pos) {
prev->rlink = newnode;
newnode->llink = prev;
newnode->rlink = curr;
curr->llink = newnode;
}
} while (curr != head);
} else {
printf("invalid position");
}
}
void delfront() {
if (head == NULL)
printf("empty list");
node *aux;
node *lastnode, *secondnode;
aux = head;
lastnode = head->llink;
secondnode = head->rlink;
secondnode->llink = lastnode;
lastnode->rlink = secondnode;
free(aux);
head = secondnode;
}
void display() {
node *aux = head;
do {
printf("%d->", aux->data);
aux = aux->rlink;
} while (aux != head);
printf("\n");
}
int main() {
insertfront(100);
insertend(20);
printf("\n%d\n", lenlist());
insertatpos(45, 2);
display();
delfront();
display();
}
The problem is not in the deletefront() function, instead, you have missed updating a few links in the insertfront() and insertend() functions.
I have updated the code here and also added the comment where I made the changes. Try to visualise it using an example.
However, I suggest that you solve such issues using a debugger or go through the code with a sample test case. It will improve you debugging as well as coding skills!
Your code have a lot of mistakes.
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
/*i changed the names of your pointers here*/
typedef struct node {
int data;
struct node *prev, *next;
} node;
/*
node *head = NULL;
This will be removed.
Avoid using globals as much as you can.
*/
/*
This function is unecessary.
node *createNode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
*/
char insertFront(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
}
*head=newNode;
return 1;
}
char insertEnd(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
*head=newNode;
}
return 1;
}
/*You could simple create a struct list that would have as members
the head of your list and its height to avoid calculating it each time
you want it but anyway. I will fix that.
int lenList(node *head) {
if (*head==NULL) return 0;
node *temp=head;
int count = 0;
do {
temp = temp->next;
count++;
} while (temp != head);
return count;
}
*/
char insertNatP(node **head, int ele, int pos) {
If (pos<1 || pos>lenList(head)){
printf("Invalid Position\n");
return 0;
}
int i;
for(i=0; i<pos-1; head=&head->next, i++);
node *newNode=malloc(sizeof(node));
If (newNode==NULL){
printf("Memory could not be allocated\n");
return 0;
}
newNode->data=ele;
If (*head!=NULL){
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode
newNode->next=*head;
} else {
newNode->prev=newNode;
newNode->next=newNode;
}
*head=newNode;
return 1;
}
char delFront(node **head) {
if (*head == NULL) return 0;
node garbage=*head;
*head=(*head)->next;
if (*head==garbage) *head=NULL; else{
(*head)->prev=garbage->prev;
garbage->prev->next=*head;
}
free(garbage);
return 1;
}
void printList(node *list) {
if (list==NULL) return;
node *sentinel=list->prev;
while (list!=sentinel) {
printf("%d->", list->data);
list=list->next;
}
printf("%d\n", list->data);
}
int main() {
node *l1=NULL;
insertFront(&l1, 100);
insertEnd(&l1, 20);
printf("\n%d\n", lenList(l1));
insertNatP(&l1, 45, 2);
printList(l1);
delFront(&l1);
printList(l1);
}
Try this
So i've been running and testing my code and everything seemed to have been working until i added 2 more functions for Pre-order and Post-order traversals of my tree.
The assignment was to create a linked list and tree for an input file with a random set of numbers. The linked list and tree traversals all need to be printed out in separate functions and i can't find where i went wrong.
i keep getting
Segmentation Fault (core dumped)
Here is my code:
//Tristan Shepherd
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct node
{
int num;
struct node *next;
};
struct tree
{
int numt;
struct tree *left;
struct tree *right;
};
typedef struct node LINK;
typedef struct tree branch;
int searchList(int number, LINK *head)
{
LINK *current;
current = head;
while (current != NULL)
{
if (current->num == number)
return 1; // Found it.
current = current->next;
}
return 0; // Did not find it.
}
LINK *insertList(int number, LINK *head)
{
LINK *current, *temp;
if (searchList(number, head) == 1) return head;
temp = (LINK *)malloc(sizeof(LINK));
temp->num = number;
if (head == NULL)
{
head = temp;
temp->next = NULL;
return head;
}
current = head;
if (current->num == number)
{
temp->next = current;
head = temp;
return head;
}
current = head;
while (current != NULL)
{
if (current->next == NULL || current->next->num == number)
{
temp->next = current->next;
current->next = temp;
return head;
}
current = current->next;
}
}
void printList(LINK *head)
{
LINK *current;
current = head;
while (current != NULL)
{
printf("%i\n", current->num);
current = current->next;
}
}
LINK *freeList(LINK *head)
{
LINK *current, *temp;
current = head;
while (current != NULL)
{
temp = current;
current = current->next;
free(temp);
}
free(head);
head = NULL;
return head;
}
void freeTree(branch *leaf)
{
if(leaf != 0)
{
freeTree(leaf->left);
freeTree(leaf->right);
free(leaf);
}
}
void insert(int new, branch **leaf)
{
if(*leaf == 0)
{
*leaf = (struct tree*) malloc(sizeof(struct tree));
(*leaf)->numt = new;
(*leaf)->left = 0;
(*leaf)->right = 0;
}
else if(new < (*leaf)->numt)
{
insert(new, &(*leaf)->left);
}
else if(new > (*leaf)->numt)
{
insert(new, &(*leaf)->right);
}
}
void printInorder(branch *leaf)
{
if (leaf == NULL)
return;
printInorder(leaf->left);
printf("%i ", leaf->numt);
printInorder(leaf->right);
}
void printPreorder(branch *leaf)
{
if (leaf == NULL)
return;
printf("%i ", leaf->numt);
printInorder(leaf->left);
printInorder(leaf->right);
}
void printPostorder(branch *leaf)
{
if (leaf == NULL)
return;
printInorder(leaf->left);
printInorder(leaf->right);
printf("%i ", leaf->numt);
}
int main (void)
{
int t;
FILE *stream = fopen("hw9.data", "r");
LINK *head;
branch *leaf;
head = NULL;
int number;
while (1)
{
fscanf(stream, "%i", &number);
if (feof(stream)) break;
insert(number, &leaf);
head = insertList(number, head);
}
fclose(stream);
printf("\nPrinting List: \n");
printList(head);
printf("\n\nPrinting in order\n");
printInorder(leaf);
printf("\n\nPrinting Pre order\n");
printPreorder(leaf);
printf("\n\nPrinting Post order\n");
printPostorder(leaf);
head = freeList(head);
freeTree(leaf);
head = NULL;
return 0;
}
branch *leaf; is not initialized. Your code expects leaf pointers to be NULL. Try branch *leaf = NULL;
Also, it looks like freeList frees head twice which is undefined behavior.
I am trying to delete a node at a specific location but I keep getting a segmentation fault 11.
I am reading the position and value from a file.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
float val;
struct node *prev;
struct node *next;
}node_t;
void printForward(node_t *head) {
node_t *current = head;
while (current != NULL) {
printf("%.2f\n", current->val);
current = current->next;
}
}
void printBackward(node_t *head) {
node_t *current = head;
while (current->next != NULL) {
current = current->next;
}
while (current != NULL) {
printf("%.2f\n", current->val);
current = current->prev;
}
}
void deleteAtPos(node_t **head, int pos) {
int i;
node_t *current = *head;
node_t *temp = NULL;
if (pos == 0) {
temp = (*head)->next;
free(*head);
(*head) = temp;
(*head)->prev = NULL;
return;
}
for (i = 0; i < (pos - 1); i++) {
if (current->next != NULL) {
current = current->next;
}
}
temp = current->next;
current->next = temp->next;
free(temp);
}
// Fix insert at position
void insertAtPos(node_t **head, int pos, float val) {
int i;
node_t *newNode = malloc(sizeof(node_t));
node_t *current = *head;
newNode->val = val;
if (pos == 0) {
newNode->next = (*head);
newNode->prev = NULL;
(*head)->prev = newNode;
(*head) = newNode;
return;
}
for (i = 0; i < pos; i++) {
if (current->next != NULL) {
current = current->next;
}
else {
printf("Node does not exist\n");
break;
}
}
current->prev->next = newNode;
newNode->prev = current->prev;
newNode->next = current;
current->prev = newNode;
}
void addEnd(node_t **head, float val) {
node_t *current = *head;
node_t *newNode = malloc(sizeof(node_t));
newNode->next = NULL;
newNode->val = val;
if (*head == NULL) {
*head = newNode;
newNode->prev = NULL;
return;
}
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Error");
}
node_t *head = NULL;
FILE *fp;
int i = 0, x;
float valLine1, valLine2, valLine3;
char buffer[200], *token, *del = ",";
float posVals[200], delPos[200];
fp = fopen(argv[1], "r");
fgets(buffer, sizeof(buffer), fp);
token = strtok(buffer, del);
while (token != NULL) {
valLine1 = atof(token);
addEnd(&head, valLine1);
token = strtok(NULL, del);
}
printForward(head);
printf("\n");
del = ":,";
fgets(buffer, sizeof(buffer), fp);
token = strtok(buffer, del);
while (token != NULL) {
valLine2 = atof(token);
posVals[i] = valLine2;
token = strtok(NULL, del);
i++;
}
for (x = 0; x < i; x += 2) {
insertAtPos(&head, posVals[x + 1], posVals[x]);
}
printForward(head);
fgets(buffer, sizeof(buffer), fp);
i = 0;
token = strtok(buffer, del);
while (token != NULL) {
valLine3 = atof(token);
delPos[i] = valLine3;
token = strtok(NULL, del);
i++;
}
printf("\n");
for (x = 0; x < i; x++) {
deleteAtPos(&head, delPos[x]);
}
printForward(head);
printf("\n");
printBackward(head);
fclose(fp);
}
The trouble is with my deleteAtPos function but I can't figure out why.
Here is the output:
24.00
0.04
17.00
-200.10
34.60
0.00
Segmentation fault: 11
And here is the contents of the file:
17,32.5,12,0,34.6,-200.1,17,0.04,24
1:2,4.1:5,-12:4
3,5,0
Please help!
Thank you
I have modified your deleteAtPos() function now you can delete at any position and your backward() function will print correct values.
void deleteAtPos(node_t **head, int pos) {
int i;
node_t *current = *head;
node_t *temp = NULL;
if (pos == 0) {
temp = (*head)->next;
free(*head);
(*head) = temp;
(*head)->prev = NULL;
return;
}
for (i = 0; i < (pos - 1); i++) {
if (current->next != NULL) {
current = current->next;
}
}
temp = current;
if(current->next==NULL)
{
current->prev->next = current->next;
}
else
{
current->prev->next = current->next;
current->next->prev = current->prev;
}
free(temp);
}
You are saying the trouble is with deleteAtPos. But your code is very far from an SSCCE, so I don't want to isolate the problem for you - you should do that, and most of the time, during the process of isolation, you will find the answer. If not, you can then post the question here.
Therefore I will just list the things I can see are wrong with deleteAtPos and maybe if you fix all of them, the problem will disappear.
You are not handling the situation where *head is NULL, the list has 0 elements. This would surely segfault.
You are not checking that pos >= 0.
You are not correctly handling the case where your list has one element, either. Another segfault.
You are not correctly handling the case where pos is the end of your list. Another segfault.
I want to write a copy_list function that creates a linked list(the function result) with new nodes that contain the same data as the linked list referenced by the single argument of copy_list.But my copy_list function doesn't work.It goes into infinite loop,While loop doesn't quit.
My structures
typedef struct name_node_s {
char name[11];
struct name_node_s *restp;
}name_node_t;
typedef struct {
name_node_t *headp;
int size;
}name_list_t;
My copy_list function:
name_node_t *copy_list(name_node_t *head){
name_node_t *current = head;
name_node_t *newList = NULL;
name_node_t *tail = NULL;
while (current != NULL){
if (newList == NULL) {
newList = malloc(sizeof(name_node_t));
strcpy(newList->name, current->name);
newList->restp = NULL;
tail = newList;
}
else {
tail->restp = malloc(sizeof(name_node_t));
tail = tail->restp;
strcpy(tail->name, current->name);
tail->restp = NULL;
}
current = current->restp;
}
return(newList);
}
Rest of code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct name_node_s {
char name[11];
struct name_node_s *restp;
}name_node_t;
typedef struct {
name_node_t *headp;
int size;
}name_list_t;
name_node_t* presidents(void);
void insertAfter(name_node_t* mynode,name_node_t* newNode);
//void delete_last(name_node_t** headRef);
//void ListDelete(name_list_t* listP, char pname[]);
void lastDelete(name_list_t* listP);
void place_first(name_node_t **headRef, char pname[]);
name_node_t *copy_list(name_node_t *head);
int main(void)
{
name_list_t list;
name_list_t list_two;
//name_node_t *np, *qp;
list.headp = presidents();
name_node_t *new_node;
new_node = malloc(sizeof(name_node_t));
strcpy(new_node->name, "Eisenhower");
insertAfter(list.headp->restp, new_node);
lastDelete(&list);
place_first(&list.headp, "Mustafa");
printf("%s %s %s %s", list.headp->name, list.headp->restp->name, list.headp->restp->restp->name, list.headp->restp->restp->restp->name);
list_two.headp = copy_list(list.headp);
printf("%s %s %s %s", list_two.headp->name, list.headp->restp->name, list.headp->restp->restp->name, list.headp->restp->restp->restp->name);
return(0);
}
name_node_t* presidents(void)
{
name_node_t* head = NULL;
name_node_t* second = NULL;
name_node_t* third = NULL;
head = malloc(sizeof(name_node_t));
second = malloc(sizeof(name_node_t));
third = malloc (sizeof(name_node_t));
strcpy(head->name, "Washington");
head->restp = second;
strcpy(second->name, "Roosevelt");
second->restp = third;
strcpy(third->name, "Kennedy");
third->restp = NULL;
return(head);
}
void insertAfter(name_node_t* mynode,name_node_t* newNode)
{
newNode->restp = mynode->restp;
mynode->restp = newNode;
}
void ListDelete(name_list_t* listP, char pname[]){
name_node_t *to_freep, *cur_nodep;
if(strcmp(listP->headp->name, pname)){
to_freep = listP->headp;
listP->headp = to_freep->restp;
--(listP->size);
}
else {
for (cur_nodep = listP->headp;
cur_nodep->restp != NULL && !strcmp(cur_nodep->restp->name, pname);
cur_nodep = cur_nodep->restp) {
if( cur_nodep->restp != NULL && strcmp(cur_nodep->restp->name, pname)) {
to_freep = cur_nodep->restp;
cur_nodep->restp = to_freep->restp;
free(to_freep);
--(listP->size);
}
}
}
}
void lastDelete(name_list_t* listP){
name_node_t *to_freep, *cur_nodep;
for (cur_nodep = listP->headp;
cur_nodep->restp != NULL;
cur_nodep = cur_nodep->restp) {}
to_freep = cur_nodep;
cur_nodep->restp = to_freep->restp;
free(to_freep);
--(listP->size);
}
void place_first(name_node_t **headRef, char pname[]) {
name_node_t *newNode = malloc(sizeof(name_node_t));
strcpy(newNode->name, pname);
newNode->restp = *headRef;
*headRef = newNode;
}
/*name_node_t *copy_list(name_node_t *head) {
name_node_t *current = head;
name_node_t *newList = NULL;
name_node_t **lastPtr;
lastPtr = &newList;
while (current != NULL) {
printf("**");
place_first(lastPtr, current->name);
lastPtr = &((*lastPtr)->restp);
current = current->restp;
}
return(newList);
}*/
/*name_node_t *copy_list(name_node_t *head) {
if (head == NULL)
return NULL;
else {
name_node_t *newList = malloc(sizeof(name_list_t));
strcpy(newList->name, head->name);
newList->restp = copy_list(head->restp);
return(newList);
}
}*/
/name_node_t *copy_list(name_node_t *head){
name_node_t *current = head;
name_node_t *newList = NULL;
name_node_t *tail = NULL;
while (current != NULL){
if (newList == NULL) {
newList = malloc(sizeof(name_node_t));
strcpy(newList->name, current->name);
newList->restp = NULL;
tail = newList;
}
else {
tail->restp = malloc(sizeof(name_node_t));
tail = tail->restp;
strcpy(tail->name, current->name);
tail->restp = NULL;
}
current = current->restp;
}
return(newList);
}
In lastDelete(), this loop:
for (cur_nodep = listP->headp;
cur_nodep->restp != NULL;
cur_nodep = cur_nodep->restp) {}
... stops at the last node in the list. Afterwards you never set restp to NULL in the second-to-last element. You only work on the last one as to_freep and cur_nodep point to the same element.
This may be easier to do recursively, since singly-linked lists are recursive structures:
A copy of NULL is just NULL.
A copy of a name_node_t is a freshly malloc'd name_node_t with the same name as the original and a copy of the original's restp as its restp.
It's been a long time since I wrote C++. Still:
Doesn't look like there's anything in copy_list that should make it go into an infinite loop.
The logic has:
while (current!=null) current = current->next;
Perhaps copy_list is being passed in a bad list? (i.e A list where the last element does not have restp == null).
In main you are calling:
insertAfter(....);
lastDelete(....);
...
copy_list(....);
So the problem could be in insertAfter or lastDelete ... or ...
Check lastDelete:
name_node_t *to_freep, *cur_nodep;
for (cur_nodep = listP->headp;
cur_nodep->restp != NULL;
cur_nodep = cur_nodep->restp) {}
to_freep = cur_nodep;
cur_nodep->restp = to_freep->restp;
free(to_freep); //what if listP->headp was null? i.e. list had size 0?
--(listP->size);
Plenty of issues
What if you're passed a list with 0 elements?
What if you're passed a list with 1 element?
In any case after you free "to_freep", the node prior to "to_freep" does not have it's restp set to null. So the second last node, now points to a deleted node! This means the list never terminates.
A better lastDelete: (just an algo, can't remember the syntax anymore...)
if (head == null) return; //do nothing
if (head->next == null)
{
listP->head = null;
listP->size = 0;
return;
}
node* prev = head;
head = head->next;
while (head->next != null)
{
prev = head;
head = head->next;
}
//now prev points to a 2nd last node
//head points to last node
free(head);
prev->restp = null;