1

I need to create a circular doubly linked list with a sentinel node which is supposed to read data from a file and insert it in the list, than perform some operations with it. For now I'm stuck on a simple print function which won't print from a list for some reason. The data in the file is in the form of strings, example: "Popular Sorting Algorithms, Bubble Sort, Merge Sort, "empty line", etc

Here is my code so far:

Header file contains:

typedef struct NODE {
 struct NODE *prev;
 char *value;
 struct NODE *next;
} NODE;

typedef struct LIST {
 int count;
 struct NODE *next;
 struct NODE *prev;
 } LIST;

int InsertEnd(NODE *head, char * value, int *lineCount);
void printLines(int *lineCount);
void Traverse(NODE *head);

Main contains:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "header.h"


int main()
{
    int lineCount = 0;
    NODE *head;

    head = (NODE *)malloc(sizeof(NODE)); /* creates head node dynamically */

    head->next = NULL;   /* points to first element */
    head->prev = NULL;   /* points to last element */
    head->value = "HEAD"; /* not needed, but it was pretty useful when debugging */

    //*********BEGIN OF OPEN FILE FUNCTION
    FILE* fp;
    char *fname = NULL;
    fname = (char *)malloc(200); <<<<<===== I would prefer to set the size dynamically adjusting but I dont know how

        printf("Reading file input.txt\n");

    //Checks if the file us unable to be opened, then it shows the error message
    if ( !(fp = fopen("input.txt", "r")))
    {
        printf("\nError, Unable to open the file for reading \n");
        exit(100);
    }

    //*********BEGIN OF READ FROM FILE FUNCTION

    while (!feof(fp))
    {
        fgets(fname, 150, fp);  //reads the file and stores in buffer

        fname[strlen(fname) - 1] = '\0'; // reduces empty strings for input

        if (fname != '\0')
        {

            InsertEnd(head, fname, &lineCount);
        //printf("%s\n", head->next->value);  <<<<==== If uncomment this print function would work properly but only in this context

        }
        else
        {
            printf("Error'\n"); // For debugging
        }

    }
    Traverse(head); // Print Function Should Be Working in Here
    printf("Debugging print\n");
    printLines(&lineCount); // Shows Line Count
    return 0;
}
// Function inserts a new node at the end of the LIST
int InsertEnd(NODE *head, char * value, int* lineCount)
{
    int lineCounter = *lineCount;
    /* create new node */
    NODE *newnode;
    newnode = (struct NODE *)malloc(sizeof( struct NODE));
    newnode->value = value;
    /* placing new node in LIST */
    if (head->next == NULL) /* LIST was empty */
    {
        newnode->next = head;
        newnode->prev = head;
        head->next = newnode;
        head->prev = newnode;
        lineCounter++;               // Increment line counter
    }
    else /* LIST wasn't empty */
    {
        newnode->next = head;
        newnode->prev = head->prev;
        head->prev->next = newnode; /* adjust node that was previously last */
        head->prev = newnode;       /* adjust head node */
        lineCounter++;                // Increment line counter
    }
    *lineCount = lineCounter;
    return lineCount;
}


// This function prints how many lines there are in the LIST, but I need to get rid of the empty spaces
void printLines(int *lineCount)
{
 printf("Line counter is %d", *lineCount);  // Shows the number of lines, but doesn't skip empty ones.
}


void Traverse(NODE *head)
{
    NODE *current = head;

    printf("Forward:");
    while (current!= head->prev)
    {
        printf("%s \n", current->value);

        current = current->next;
    }
    printf("\n");
}

Therefore, I have several problems so far:

1) I need to get rid of empty strings in my list most likely. What would be a better approach, to get rid of them while reading or just not displaying when printing? How would I do this exactly?

2) How can I fix my print(traverse) function and whats wrong there?

3) Additionally all of this should be going on through the menu manager which would prompt for a command ( I got this right I think). But there are some functions that I don't know how to implement. For example when used hits "I" it should call Insert functions and prompt the user to enter two more values and , and later insert at the appropriate . How would I do that? Example "I 1 8"

4) Similarly to the previous one, there should be List function which should print lines between specific values. User input format should be "L to " list inclusively. Example "L 2 5"

5) Similarly to previous there should be a delete function with the format "D " inclusively. Example "D 3 7"

6) And the very last is the Save function in the format "S " Example "S output.txt"

Thank You for the help!

Denys Korovets
  • 75
  • 1
  • 12
  • You can add this to your list of things to address: [`while (!feof(fp))` is wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). And the ensuring `fgets()` is completely unchecked for potential failure before assuming it worked. – WhozCraig Feb 18 '14 at 08:15

2 Answers2

0

I see at least these issues in your code,

In main()

 if (fname != '\0') 

this should be

 if (fname[0] != '\0')     

In InsertEnd()

newnode->value = value;

should be

newnode->value = strdup(value);    
Rohan
  • 52,392
  • 12
  • 90
  • 87
0

In you code there should be some correctness which is very help full first as per your request you need to allocate buffer dynamically but not know file length so it can be achived by this one

int sz;
printf("Reading file input.txt\n");

//Checks if the file us unable to be opened, then it shows the error message
if ( !(fp = fopen("sample.txt", "r")))
{
    printf("\nError, Unable to open the file for reading \n");
    exit(100);
}

fseek(fp, 0L, SEEK_END);
sz = ftell(fp);

printf("size of file %d\n",sz);

fname = (char *)malloc(sz);
rewind(fp);

Now for reading content from file you checked fname to \0 which is not correct i corrected your while..loop.

while (!feof(fp))
{
    if(fgets(fname,256, fp) != 0)
    {
        fname[strlen(fname) - 1] = '\0'; // reduces empty strings for input
        InsertEnd(head, fname, &lineCount);
    }
    else
    {
        printf("Error'\n"); // For debugging
    }
}
Jayesh Bhoi
  • 24,694
  • 15
  • 58
  • 73