Thread: Trying to use a stringlist to read contents of a directory using doubly linked list.

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    11

    Trying to use a stringlist to read contents of a directory using doubly linked list.

    can anyone help me? here is my problem.

    everytime i try to print the head node data and current node data, only first 25 characters from the string are printed.

    here is the source code..

    Code:
    // main.c
    
    #include "libdirectory/libdirectory.h"
    #include <stdio.h>
    
    int main( int argc, char *argv[])
    {
        stringlist sl = directory_read_contents("/home/dipesh/Pictures");
    
        stringlist s = string_list_init();
    
    
        string_list_append(&s, "asdfghklqwertyyui");
        string_list_append(&s, "asdfghklqwertyyuifsddffop");
    
    
        //printf("%s\n", s.head->data);
        //printf("%d\n", string_length(s.head->data));
        //printf("%d\n", string_length(sl.head->data));
        /*while ( sl.current != sl.tail ) {
            printf("%s\n", sl.current->data);
            string_list_next(&sl);
        }*/
        string_list_free(&sl);
        string_list_free(&s);
    
        return 0;
    }
    Code:
    // libstringman.h
    
    #include <stdlib.h>
    
    #define FALSE 0
    #define TRUE !FALSE
    
    typedef int boolean;
    
    typedef enum {
        STRING_LIST_SORT_NONE,
        STRING_LIST_SORT_ASCENDING,
        STRING_LIST_SORT_DESCENDING
    }stringlistsorttype;
    
    
    struct _stringnode {
        int index;
        char *data;
        struct _stringnode *next;
        struct _stringnode *prev;
    };
    typedef struct _stringnode stringnode;
    
    
    struct _stringlist {
        stringnode *head;
        stringnode *tail;
        stringnode *current;
        int len;
    
    };
    typedef struct _stringlist stringlist;
    
    // String Operations
    char *string_copy(char *src); // copies the string from src and returns the destination string
    int string_length(char *str); // returns the length of the string
    char *string_join(char *str1, char *str2); // joins the str1 and str2, returns a new string
    boolean string_is_equal(char *str, char *str2); // checks whether two strings are equal. not similar to strcmp.
    char *string_split(char *str, char delimiter); // splits a string using a delimiter
    
    // String List
    stringlist string_list_init(void);
    void string_list_append(stringlist *sl, char *str);
    void string_list_next(stringlist *sl);
    void string_list_prev(stringlist *sl);
    void string_list_free(stringlist *sl);
    Code:
    // libstringman.c
    
    #include "libstringman.h"
    #include <stdio.h>
    
    char *string_copy(char *src)
    {
        char *dest = NULL;
        int i = 0;
    
        dest = (char *)malloc(sizeof(string_length(src)));
    
        while ( src[i] != '\0' ) {
            dest[i] = src[i];
            i++;
        }
        dest[i] = '\0';
        return dest;
    }
    
    int string_length(char *str)
    {
        int i = 0;
        char temp = str[0];
    
        while ( temp != '\0' ) {
            temp = str[++i];
        }
        return i;
    }
    
    char *string_join(char *str1, char *str2)
    {
        char *temp = NULL;
        int i = 0, j = 0;
    
        temp = malloc(sizeof(string_length(str1) + string_length(str2)));
    
        while ( str1[i] != '\0' ) {
            temp[i] = str1[i];
            i++;
        }
    
        while ( str2[j] != '\0' ) {
            temp[i++] = str2[j++];
        }
    
        return temp;
    }
    
    boolean string_is_equal(char *str1, char *str2)
    {
        if ( string_length(str1) != string_length(str2) ) {
            return FALSE;
        } else {
            int i = 0;
    
            while ( str1[i] != '\0' || str2[i] != '\0' ) {
                if ( str1[i] != str2[i] )
                    return FALSE;
                i++;
            }
            return TRUE;
        }
    }
    
    char *string_split(char *str, char delimeter)
    {
        char *temp = NULL;
        int i = 0, j = 0, flag = 0;
    
        while ( str[i] != '\0' ) {
            if ( str[i] == delimeter )
                flag = 1;
            if ( flag == 0 )
                i++;
            else {
                i++;
                j++;
            }
        }
    
        temp = malloc(j);
    
        i = i - j;
        j = 0;
        while ( str[i] != '\0' ) {
            temp[j] = str[i];
            i++;
            j++;
        }
        temp[j] = '\0';
    
        return temp;
    }
    
    stringlist string_list_init(void)
    {
        stringlist sl;
        sl.len = 0;
        sl.current = NULL;
        sl.head = NULL;
        sl.tail = NULL;
    
        return sl;
    }
    
    void string_list_append(stringlist *sl, char *str)
    {
        stringnode *temp = NULL;
    
        temp = (stringnode *)malloc(sizeof(stringnode));
        temp->data = string_copy(str);
        //printf("%s\n", temp->data);
    
        if ( sl->len == 0 ) {
            temp->index = 0;
            temp->next = NULL;
            temp->prev = NULL;
            sl->head = temp;
            sl->tail = temp;
            sl->len = 1;
            sl->current = sl->tail;
            printf("head : %s\n", sl->head->data);
            printf("tail : %s\n", sl->tail->data);
            printf("current : %s\n", sl->current->data);
        } else {
            temp->index = sl->len++;
            temp->next = NULL;
            temp->prev = sl->tail;
            sl->tail->next = temp;
            sl->tail = temp;
            printf("head : %s\n", sl->head->data);
            printf("tail : %s\n", sl->tail->data);
            printf("current : %s\n", sl->current->data);
        }
        //printf("%s\n", sl->current->data);
        temp = NULL;
    }
    
    void string_list_next(stringlist *sl)
    {
        sl->current = sl->current->next;
        if ( sl->current == NULL )
            sl->current = sl->head;
    }
    
    void string_list_prev(stringlist *sl)
    {
        sl->current = sl->current->prev;
        if ( sl->current == NULL )
            sl->current = sl->tail;
    }
    
    void string_list_free(stringlist *sl)
    {
        stringnode *temp;
    
        sl->current = sl->head;
    
        while ( sl->current != NULL ) {
            temp = sl->current->next;
            free(sl->current);
            sl->current = temp;
        }
        free(sl->head);
        free(sl->tail);
        sl->head = NULL;
        sl->tail = NULL;
        sl->len = 0;
    }
    Code:
    // libdirectory.h
    
    #include <dirent.h>
    #include <sys/stat.h>
    #include "../libstringman/libstringman.h"
    
    stringlist directory_read_contents(char *path);
    Code:
    // libdirectory.c
    
    #include "libdirectory.h"
    #include <stdio.h>
    
    stringlist directory_read_contents(char *path)
    {
        struct stat st;
        DIR *dir;
        struct dirent *drent;
        stringlist sl = string_list_init();
    
        stat(path, &st);
    
        if ( S_ISDIR(st.st_mode) ) {
            dir = opendir(path);
            while ( drent = readdir(dir) ) {
                string_list_append(&sl, drent->d_name);
            }
        }
    
        return sl;
    }
    Code:
    head : widescreen-landscape-99-1920x1200.jpg  <-- first time, its printing fine
    tail : widescreen-landscape-99-1920x1200.jpg
    current : widescreen-landscape-99-1920x1200.jpg
    head : widescreen-landscape-99-1                    <-- from the second time, only 25 characters
    tail : BloodDragon_wallpaper_wide_1680x1050.jpg
    current : widescreen-landscape-99-1
    head : widescreen-landscape-99-1
    tail : original1.jpeg
    current : widescreen-landscape-99-1
    head : widescreen-landscape-99-1
    tail : original.jpeg
    current : widescreen-landscape-99-1
    head : widescreen-landscape-99-1
    tail : 128.jpeg
    current : widescreen-landscape-99-1
    head : widescreen-landscape-99-1
    tail : 2011-05-18-132559.jpg
    current : widescreen-landscape-99-1
    head : widescreen-landscape-99-1
    tail : 87.jpeg
    current : widescreen-landscape-99-1
    head : widescreen-landscape-99-1
    tail : 52.jpeg
    i've also attached the original source file..
    Attached Files Attached Files

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    It's quite hard to believe that you write a bunch of code which you can't debug. or narrow it down....
    Try to use a debugger ?
    How about unit testing before fitting all pieces together?

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    11
    i'm tried using gdb. its not helping me fix my problem.

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    278
    You have an awful lot of code there for the folks here to walk through.

    Can you debug and watch what happens to what you are trying to print?
    Can you strip the code down to the bare minimum to illustrate the problem and then repost?

    My first guess would be that since you are using %s to print, the thing you are printing got stepped on, thereby terminating the "string". But that's just a guess.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > temp = malloc(sizeof(string_length(str1) + string_length(str2)));
    Lessons on when it is inappropriate to use sizeof() when calling malloc.

    But beware, when you fix that, there is still another mistake in that line to be fixed.

    Ditto in the other places where you try to allocate space for a string.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    May 2011
    Posts
    11
    Quote Originally Posted by Salem View Post
    > temp = malloc(sizeof(string_length(str1) + string_length(str2)));
    Lessons on when it is inappropriate to use sizeof() when calling malloc.

    But beware, when you fix that, there is still another mistake in that line to be fixed.

    Ditto in the other places where you try to allocate space for a string.
    i changed the line to temp = malloc(string_len(str1) + string_length(str2));
    i also changed the similar line in string_copy function which solved my problem.

    Thanks a lot.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > But beware, when you fix that, there is still another mistake in that line to be fixed.
    Like I said - there were TWO issues to fix.

    All you've done so far is make the problem a lot less likely, not fixed it altogether.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    May 2011
    Posts
    11
    i'm not sure what the other issue is. is it casting the new memory of the malloc function?

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    OK, quick quiz - how many bytes do you need to make a copy of an empty string (or join two empty strings together).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    May 2011
    Posts
    11
    to copy an empty string, 1 byte i think for '\0' or the number of bytes reserved for the empty string.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Yes, and does your code do this correctly?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    May 2011
    Posts
    11
    Code:
        char *str1 = "";
        char *str2 = "";
        char *str3 = string_join(str1, str2);
        char *str4 = "";
        char *str5 = string_copy(str4);
        char *str6 = "Hello";
        char *str7 = string_copy(str5);
    
        printf("str1 = %u\n", sizeof(str1));
        printf("str2 = %u\n", sizeof(str2));
        printf("str3 = %u\n", sizeof(str3));
        printf("str4 = %u\n", sizeof(str4));
        printf("str5 = %u\n", sizeof(str5));
        printf("str6 = %u\n", sizeof(str6));
        printf("str7 = %u\n", sizeof(str7));
    i get..

    Code:
    str1 = 8
    str2 = 8
    str3 = 8
    str4 = 8
    str5 = 8
    str6 = 8
    str7 = 8

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What does sizeof have to do with anything?

  14. #14
    Registered User
    Join Date
    May 2011
    Posts
    11
    i sill don't get it.

  15. #15
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So suppose you are supposed to join the strings "abra" and "cadabra" together. What size do you need for the final product? What is the strlen (not sizeof) of each of the parts? If you add them together, what do you get?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with doubly linked list
    By Furbiesandbeans in forum C++ Programming
    Replies: 2
    Last Post: 11-03-2008, 11:41 AM
  2. doubly linked list
    By bahareh in forum C++ Programming
    Replies: 7
    Last Post: 03-28-2007, 01:31 PM
  3. singly linked list to doubly linked list
    By t48j in forum C Programming
    Replies: 3
    Last Post: 03-23-2005, 06:37 PM
  4. Doubly Linked List.. please Help!!
    By ProgrammingDlux in forum C++ Programming
    Replies: 8
    Last Post: 10-24-2004, 08:27 PM
  5. read directory contents
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 04-04-2002, 11:19 AM