The first time addToEnd()
is called it works but the second time it crashes the program. I've been trying to debug it and found it happens when head->next
happens. I'm a little confused because it's just being read, can that crash the program? If yes how can you possible itterate through the file?
It seems to work on certain values of entry
but not others. If two entry's are the same and composed all of one letter it crashes. So if addToEnd(head, "aaaaaaaaa") is called then addToEnd(head, "aaaaaaaaa") is called the program crashes but if addToEnd(head, "aaaaaaaaa") then addToEnd(head, "aaaaaaaab") it is fine.
Here is 100% all of the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct node
{
char entry[21];
struct node* next;
} node;
void readDic();
void reverStr(char *str);
bool isInDic(char *reversed);
void addToEnd(node* head, char entry[21]);
unsigned int searchAndDestroy(node **head, char *entry);
void printList(node* head);
int main()
{
printf("Hello\n");
readDic();
printf("Goodbye!");
return EXIT_SUCCESS;
}
void readDic()
{
FILE* words;
char singleLine[21];
words = fopen("words.txt", "r");
node* head = malloc(sizeof(node));
fscanf(words, "%20s", head->entry);//need to do this initially
head->next = NULL;
printf("here 0");
printf("here 0.1");
if(words == NULL)
exit(EXIT_FAILURE);
printf("here 0.5");
while(fscanf(words, "%20s", singleLine) == 1)assigned input terms
{
printf("\nhere 0.6\n|%s|", singleLine);
addToEnd(head, singleLine);//problem here
printf("here 0.7");
reverStr(singleLine);
printf("here 1");
if(isInDic(singleLine)){
printf("here 2");
searchAndDestroy(&head, singleLine);
printf("here 3");
}
}
printf("here 4");
fclose(words);
printList(head);
printf("here 5");
}
//http://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c
/* PRE: str must be either NULL or a pointer to a
* (possibly empty) null-terminated string. */
void reverStr(char *str)
{
char temp, *end_ptr;
/* If str is NULL or empty, do nothing */
if(str == NULL || !(*str))
return;
end_ptr = str + strlen(str) - 1;
/* Swap the chars */
while( end_ptr > str )
{
temp = *str;
*str = *end_ptr;
*end_ptr = temp;
str++;
end_ptr--;
}
}
bool isInDic(char* reversed)
{
FILE* words;
char singleLine[21];
words = fopen("words", "r");
if(words == NULL)
exit(EXIT_FAILURE);
while(fscanf(words, "%20s", singleLine) == 1)//the length of the string has to be 1 less than declared size for the newline character
{
//printf("singline: %s reversed: %s\n", singleLine, reversed);
if(strcmp(singleLine, reversed) == 0)//strcmp returns 0 if both cstrings are equal
return true;
}
fclose(words);
return false;
}
void addToEnd(node* head, char entry[21])
{
printf("hi");
//printf("\naddress of next %p\n", (void *)head->next);
while(head->next != NULL)//just reading head->next screws it up
head = head->next;
printf("in addToEnd 2\n");
node* last = (node*)malloc(sizeof(node));
printf("in addToEnd 3\n");
head->next = last;
printf("in addToEnd 4\n");
strcpy(last->entry, entry);
printf("in addToEnd 5\n");
last->next = NULL;
printf("in addToEnd 6\n");
}
unsigned int searchAndDestroy(node **head, char *entry)
{
unsigned int count = 0;
while(*head)
{
node *del;
if(strcmp((*head)->entry, entry))
{ //this node stays
head = &(*head)->next;
continue;
}
/* this node goes
at this point head MUST point to the pointer that points at the node to be deleted
*/
del = *head;
*head = (*head)->next;
free(del);
count++;
}
return count; //number of nodes deleted
}
void printList(node* head)
{
printf("\nprinting everything\n");
if(head != NULL)
{
while(head->next != NULL)
{
printf("%s", head->entry);
head = head->next;
}
printf("%s", head->entry);
}
}
The answers are correct that head is being set to null
but I don't see where?