I build a doubly linked list which orders strings in alphabetical order as you add them. The strings come from an input file and I use getopt to get the input file from the command line. When i test the doubly linked list by itself it works fine and sorts the words accordingly, but once I use the strings from the file, the strcmp always returns 0.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h>
#include <stdbool.h>
#include <unistd.h>
typedef struct Node{
char *word;
struct Node *next;
struct Node *prev;
}Node;
Node *head = NULL;
Node *tail = NULL;
Node* createNode(char *word){
Node *newNode = malloc(sizeof(Node));
newNode->word = word;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}
int compare(char *word, char *current){
return strcmp(word, current);
}
void insertNode(Node *newNode){
if(head == NULL){
head = newNode;
tail = newNode;
return;
}
Node *current = head;
int comp;
do{
comp = compare(newNode->word, current->word);
printf("word: %s, current: %s, comp = %d\n",newNode->word, current->word, comp);
//Only inserting node when word is less than current
if(comp < 0){
if(current->prev == NULL){
head = newNode;
current->prev = head;
head->next = current;
return;
}
newNode->next = current;
newNode->prev = current->prev;
current->prev->next = newNode;
current->prev = newNode;
printf("comp: %d, New node added for: %s\n\n", comp, newNode->word);
return;
}
if(comp > 0 && current->next == NULL){
current->next = newNode;
newNode->prev = current;
tail = newNode;
printf("New node: %s, added at the tail\n\n", newNode->word);
return;
}
//printf("past first if\n");
if(comp > 0 && current->next){
printf("enter com > 0\n");
printf("current: %s\n", current->word);
current = current->next;
printf("current updated: %s\n\n", current->word);
}
//If both words are equal just drop newNode
if(comp == 0){
//free(newNode);
return;
}
} while(current != NULL);
}
void printList(int reverse){
if (reverse == 0){
Node *current = head;
while (current != NULL) {
printf("%s\n", current->word);
current = current->next;
}
} else if(reverse == 1){
Node *current = tail;
while (current != NULL) {
printf("%s\n", current->word);
current = current->prev;
}
}
}
void printListFile(FILE* fp, int reverse) {
if (reverse == 0){
Node *current = head;
while (current != NULL) {
fprintf(fp, "%s\n", current->word);
current = current->next;
}
} else if(reverse == 1){
Node *current = tail;
while (current != NULL) {
fprintf(fp, "%s\n", current->word);
current = current->prev;
}
}
}
void freeList() {
while (head != NULL) {
Node* next = head->next;
free(head->word);
free(head);
head = next;
}
}
int main(int argc, char **argv) {
extern char *optarg;
extern int optind;
int dflag = 0, oflag = 0;
char* inputFile = NULL;
char* outputFile = NULL;
int c, err = 0;
//Usage
static char usage[] = "usage: %s doublesort [-d] [-o output_file_name] input_file_name\n";
//Getopt
while ((c = getopt(argc, argv, "do")) != -1)
switch (c) {
case 'd':
dflag = 1;
break;
case 'o':
oflag = 1;
outputFile = optarg;
break;
case '?':
err = 1;
break;
}
if (err) {
fprintf(stderr, usage, argv[0]);
exit(1);
}
if (optind >= argc) {
printf("optind = %d, argc = %d\n", optind, argc);
fprintf(stderr, "%s: missing input file name\n", argv[0]);
fprintf(stderr, usage, argv[0]);
return 1;
}
if (optind < argc) {
inputFile = argv[optind];
}
FILE* fin = stdin;
FILE* fout = stdout;
if (inputFile != NULL) {
fin = fopen(inputFile, "r");
if (fin == NULL) {
fprintf(stderr, "Error: cannot open file %s for reading.\n", inputFile);
return 1;
}
}
if(oflag == 1){
if (outputFile != NULL) {
fout = fopen(outputFile, "w");
if (fout == NULL) {
fprintf(stderr, "Error: cannot open file %s for writing.\n", outputFile);
if (fin != stdin) {
fclose(fin);
}
return 1;
}
}
}
//Inserting node into doubly link list
char buf[100];
while (fgets(buf, sizeof(buf), fin) != NULL) {
int len = strlen(buf);
if (len > 0 && buf[len - 1] == '\n') {
buf[len - 1] = '\0';
}
insertNode(createNode(buf));
}
if(oflag == 1){
printListFile(fout, dflag);
}
else{
printList(dflag);
}
// free memory and close files
freeList();
if (fin != stdin) {
fclose(fin);
}
if (fout != stdout) {
fclose(fout);
}
return 0;
}
I feel like its an issue with the head storing but not sure how. Im new to C and we are using putty/UNIX which makes it more difficult.