Thread: Linked List

  1. #1
    Registered User
    Join Date
    May 2013
    Posts
    17

    Lightbulb Linked List

    My program takes in an input file from the command line and converts the string from the file into a linked list and then depending on the command it will manipulate the string to either reverse the list, print the list, or take a character out...I'm having trouble taking a character out, my code compiles fine but doesn't change the string at all

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define SIZE 1024
    
    
    
    
    typedef struct node
    {
    	char data;
    
    
    	struct node *next;
    } node;
    
    int main(int argc, char **argv)
    {
        char chr;
        char str[SIZE];
        char key;
        char buffer[SIZE];
    
    
        FILE *file = fopen(argv[1], "r");
    
    
        if (file == 0)
        {
            printf("Could not open file\n");
        }
    
    
        fgets(buffer, SIZE, file);
        node *new_head = stringToList(buffer);
    
    
        while(fscanf(file, " %c", &chr) != EOF){
    
    
        if(chr == '!')
            printList(new_head);
    
    
        if(chr == '~')
            new_head = reverseList(new_head);
    
    
        if(chr == '-')
            {
                fscanf(file, "%c", &key);
                fscanf(file, "%s", str);
                new_head = replaceChar(new_head, key, "");
            }
        }
    
    
        fclose(file);
    
    
        return 0;
    }
    
    
    node *stringToList(char *str)
    {
        node *temp = NULL;
        node *tail = NULL;
    
    
        for(; *str != '\0'; str++)
            {
                if (temp==NULL)
                {
                    temp=(node*)malloc(sizeof(node));
                    temp->data = *str;
                    temp->next = NULL;
                    tail = temp;
                }
                else
                {
                    tail->next = (node*)malloc(sizeof(node));
                    tail = tail->next;
                    tail->data = *str;
                    tail->next = NULL;
                }
            }
    
    
        return temp;
    }
    
    
    node *replaceChar(node *head, char key, char *str)
    {   node *temp;
    
    
        if(head == NULL)
            return NULL;
    
    
        if(head->data == key)
        {
            temp = head->next;
            free(head);
            return temp;
        }
    
    
        head->next = replaceChar(head->next, key, "");
    
    
        return head;
    }
    
    
    node *reverseList(node *head){
    
    
        node *temp;
        node *rev_head = NULL;
    
    
        while(head != NULL){
            temp = head->next;
            head->next = rev_head;
            rev_head = head;
            head = temp;
        }
    
    
        return rev_head;
    }
    
    
    void printList(node *temp)
    {
        node *p;
    
    
        for(p=temp; p != NULL; p = p->next)
        {
            printf("%c", p->data);
        }
    
    
        printf("\n");
    }
    The input.txt file has the following

    hello
    !
    ~
    - e
    !

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Your code does not compile fine (turn your compiler's warning level up to the max):
    Code:
    $ make list
    gcc -Wall -ggdb3 -std=c99 -o list list.c -lm -lpthread
    list.c: In function ‘main’:
    list.c:34:3: warning: implicit declaration of function ‘stringToList’ [-Wimplicit-function-declaration]
    list.c:34:20: warning: initialization makes pointer from integer without a cast [enabled by default]
    list.c:41:7: warning: implicit declaration of function ‘printList’ [-Wimplicit-function-declaration]
    list.c:45:7: warning: implicit declaration of function ‘reverseList’ [-Wimplicit-function-declaration]
    list.c:45:16: warning: assignment makes pointer from integer without a cast [enabled by default]
    list.c:52:7: warning: implicit declaration of function ‘replaceChar’ [-Wimplicit-function-declaration]
    list.c:52:16: warning: assignment makes pointer from integer without a cast [enabled by default]
    list.c: At top level:
    list.c:64:7: error: conflicting types for ‘stringToList’
    list.c:34:20: note: previous implicit declaration of ‘stringToList’ was here
    list.c:93:7: error: conflicting types for ‘replaceChar’
    list.c:52:18: note: previous implicit declaration of ‘replaceChar’ was here
    list.c:116:7: error: conflicting types for ‘reverseList’
    list.c:45:18: note: previous implicit declaration of ‘reverseList’ was here
    list.c:135:6: warning: conflicting types for ‘printList’ [enabled by default]
    list.c:41:7: note: previous implicit declaration of ‘printList’ was here
    Those are all basically the same type of warning. Your function definitions are placed after you use them. The C compiler reads your source file top to bottom, and doesn't know about anything it hasn't read yet, so when you call stringToList on line 34, the compiler can't check that you're calling it correctly (correct parameter count and type, and correct return type). Either move the function definitions up in the file, before you call them, or put function prototypes near the top of your file (between the typedef and main), so the compiler knows what they look like and can do proper type checking.

    Next:
    Code:
    $ ./list 
    Could not open file
    Segmentation fault (core dumped)
    If you can't open the file, you print a message, but let the program continue, which causes a seg fault (the file handle is NULL). You should fail gracefully, by exiting with an error code.


    You're having a minor fscanf issue. I added the following line (after the two fscanf calls around line 52), which produced the following output when I ran against the input file you provided:
    Code:
    printf("replacing key = [%c], str = [%s]\n", key, str);
    // output
    // replacing key = [ ], str = [e]
    Notice, key is a space char, and str (whatever that is used for) is the letter e. I'm guessing that is not what you want, rather you want to remove the letter 'e' from the string. The problem is with your fscanf call. The %c matches any character, including white space (unlike most other format specifiers, which skip over white space -- a confusing nuance of scanf). Put a space before the %c there, to cause scanf to skip the white space, and (possibly) remove the str since I don't think you need it:
    Code:
    if(chr == '-')
    {
        fscanf(file, " %c", &key);  // note the space
        new_head = replaceChar(new_head, key, "");
    }
    Last edited by anduril462; 07-10-2013 at 12:29 PM. Reason: clarifications

  3. #3
    Registered User
    Join Date
    May 2013
    Posts
    17
    Wow thanks for your help, its compiling and taking out the character...the only problem I am having is that say I have the word telephone in my input.txt document it only takes out the first e and not the other one too

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Notice that, if your function finds the key to replace, it does so, then returns the remainder of the list. It never calls itself recursively in that case (only when it doesn't find the key).

    Honestly, I would not bother bother with making that a recursive function, however if you really want to (or must), it's fine. Note, you can simplify this a bit, to only include one recursive call, and one return statement (excluding the base case).

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    well looks like to remove all occurrences you need in line 105 replace the return temp with
    Code:
    head = temp;
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Declaring linked list inside linked list
    By blueboyz in forum C Programming
    Replies: 33
    Last Post: 04-20-2012, 10:13 AM
  2. Replies: 4
    Last Post: 05-01-2010, 10:19 PM
  3. single linked list to double linked list (help)
    By Countfog in forum C Programming
    Replies: 8
    Last Post: 04-29-2008, 08:04 PM
  4. singly linked list to doubly linked list
    By t48j in forum C Programming
    Replies: 3
    Last Post: 03-23-2005, 06:37 PM
  5. Replies: 6
    Last Post: 03-02-2005, 02:45 AM

Tags for this Thread