Thread: Printing word from a txt file (platform: UNIX)

  1. #1
    Registered User
    Join Date
    Oct 2004
    Posts
    31

    Printing word from a txt file (platform: UNIX)

    Hi
    The following code is supposed to print the words(txt) from a file to stdout. I am using Double Linked list cause I am asked to do so. But the problem is... (marked by ERROR in the code listing), when I run it it gives me a seg fault. instead of using %s if I use %c as mentioned inside, I can only print the 1st char of the words. How can I fix it.. please please

    ****************************
    Code:
    #include <stdio.h>
    #define  NullChar    '\0'
    #define  NewLine     '\n'
    
    struct NODE
    {
       struct NODE *pNext;
       struct NODE *pPrev;
       char* nData;
    }*pHead, *pTail;
    
    void AppendNode(struct NODE *pNode);
    void InsertNode(struct NODE *pNode, struct NODE *pAfter);
    
    void AppendNode(struct NODE *pNode)
    {
        if (pHead == NULL) {
            pHead = pNode;
            pNode->pPrev = NULL;
        }
        else {
            pTail->pNext = pNode;
            pNode->pPrev = pTail;
        }
        pTail = pNode;
        pNode->pNext = NULL;
    }
    
    
    void InsertNode(struct NODE *pNode, struct NODE *pAfter)
    {
        pNode->pNext = pAfter->pNext;
        pNode->pPrev = pAfter;
    
        if (pAfter->pNext != NULL)
            pAfter->pNext->pPrev = pNode;
        else
            pTail = pNode;
        pAfter->pNext = pNode;
    }
    
    
    
    void main()
    {
        struct  NODE *pNode;
        int i;
    
        FILE *instream=fopen("words.csv","r");
    
        char *word[100];
        int k=0;
    
        while(k != -1)
            {
                pNode = malloc (sizeof (struct NODE));
                k= pNode->nData = getword(word,100,instream);;
                AppendNode(pNode);
            }
    /*ERROR HERE ::STARTS (only prints one char if used %c else give seg error if used %s*/
     for( pNode=pHead;pNode !=Null; pNode=pNode->nNext)
     {
       printf("%s",pNode->nData);
     }
    /*ERROR HERE::ENDS*/
    
    }
    
    
    /* getword:  get next word or character from input */
    int getword(char *word, int lim, FILE * instream)
    {
        int c;
        char *w = word;
        while ((isspace(c = fgetc(instream))) && (c !='\n'))
            ;
    
    
        if (c != EOF)
            *w++ = c;
    
        if (!isalpha(c) ) {
            *w = NullChar;
            return c;
        }
    
        for ( ; --lim > 0; w++)
            if (!isalnum(*w = fgetc(instream))) {
                ungetc(*w,instream);
                break;
            }
        *w = NullChar;
        if (c == EOF)
            return EOF;
        return word[0];
    }
    Last edited by swagatob; 10-09-2004 at 10:21 AM.

  2. #2
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    hello, internet!

  3. #3
    Registered User
    Join Date
    Oct 2004
    Posts
    31
    please anyone? I need to go home to eat.... *crying*

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Well first of all, you have the variable word declared as an array of character pointers, not as an array of characters.

    Secondly, the word array is shared by every node. This means once you create a new node, the array gets overwritten.

    Try something more like....
    Code:
    char *word;
        int k=0;
    
        while(k != -1)
            {
                word = malloc(100 * sizeof(char));
                pNode = malloc (sizeof (struct NODE));
                k= pNode->nData = getword(word,100,instream);;
                AppendNode(pNode);
            }

  5. #5
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by bithub
    Code:
    char *word;
        int k=0;
    
        while(k != -1)
            {
                word = malloc(100 * sizeof(char));
                pNode = malloc (sizeof (struct NODE));
                k= pNode->nData = getword(word,100,instream);;
                AppendNode(pNode);
            }
    sizeof(char) is guaranteed to be 1. It might be appropriate to do something like this:

    Code:
    word = malloc(100 * sizeof(*word));
    ~/
    Last edited by kermit; 10-09-2004 at 08:34 PM.

  6. #6
    Registered User
    Join Date
    Oct 2004
    Posts
    31
    Code:
        char *word; /*[100];*/
        int k=0;
        while(k != -1)
            {
                word=malloc(100 * sizeof(word));
                pNode = malloc (sizeof (struct NODE));
                k= pNode->nData = getword(word,100,instream);
                AppendNode(pNode);
            }
    
        for(pNode=pHead; pNode->nData != '\n'; pNode=pNode->pNext)
            {
                printf("%s",pNode->nData);
            }
                DeleteAllNodes();
    I still get a seg fault after the changes. It seems like when I change to %c (from %s) in printing the data, it prints only the first characters. But with %s, it gives me a seg error. any ideas?

  7. #7
    Registered User
    Join Date
    Oct 2004
    Posts
    31
    Please anyone? It seems like I cant initialize pNode to pHead. why would that be?

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > k= pNode->nData = getword(word,100,instream);
    Do you even get any warnings from this?

    It would be better for getword to return a char* (and hence return NULL at the end of input) than what you are doing at the moment.

    Code:
    #include <stdio.h>
    #include <stdlib.h>             /* for malloc */
    #include <ctype.h>
    
    #define  NullChar    '\0'
    #define  NewLine     '\n'
    
    struct NODE {
        struct NODE *pNext;
        struct NODE *pPrev;
        char *nData;
    } *pHead, *pTail;
    
    void AppendNode(struct NODE *pNode);
    void InsertNode(struct NODE *pNode, struct NODE *pAfter);
    char *getword(char *word, int lim, FILE * instream);
    
    void AppendNode(struct NODE *pNode)
    {
        if (pHead == NULL) {
            pHead = pNode;
            pNode->pPrev = NULL;
        } else {
            pTail->pNext = pNode;
            pNode->pPrev = pTail;
        }
        pTail = pNode;
        pNode->pNext = NULL;
    }
    
    
    void InsertNode(struct NODE *pNode, struct NODE *pAfter)
    {
        pNode->pNext = pAfter->pNext;
        pNode->pPrev = pAfter;
    
        if (pAfter->pNext != NULL)
            pAfter->pNext->pPrev = pNode;
        else
            pTail = pNode;
        pAfter->pNext = pNode;
    }
    
    
    
    int main()
    {                               /* main returns int - AWLAYS! */
        struct NODE *pNode;
        FILE *instream = stdin /*fopen("words.csv","r") */ ;
        char *word;
        char *k = 0;
    
        do {
            word = malloc(100 * sizeof *word);
            pNode = malloc(sizeof *pNode);
            k = pNode->nData = getword(word, 100, instream);
            AppendNode(pNode);
        } while ( k != NULL );
    /*ERROR HERE ::STARTS (only prints one char if used %c else give seg error if used %s*/
        for (pNode = pHead; pNode != NULL; pNode = pNode->pNext) {
            printf("%s\n", pNode->nData);
        }
    /*ERROR HERE::ENDS*/
        return 0;
    }
    
    
    /* getword:  get next word or character from input */
    char *getword(char *word, int lim, FILE * instream)
    {
        int foundword = 0;
        char *w = word;
        while ( lim > 0 ) {
            int c = fgetc(instream);
            if ( c == EOF ) { word = NULL; break; }
            if ( !foundword && isspace(c) ) continue;
            foundword = 1;
            if ( isalnum(c) ) {
                *w++ = c;
                *w = NullChar;
                lim--;
            } else {
                ungetc(c, instream);
                break;
            }
        }
        return word;
    }
    Sort of works, there are a couple of things to fix.
    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.

  9. #9
    Registered User
    Join Date
    Oct 2004
    Posts
    31
    thanks all. It works now. Well that is part of my main code. I am writting a unix utility like the "d i ff" . Thank you so much. You guys have been able to find the erros that I was scratching my head for couple of days.

    I am so grateful to all of you guys.

    Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A development process
    By Noir in forum C Programming
    Replies: 37
    Last Post: 07-10-2011, 10:39 PM
  2. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  3. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  4. Replies: 2
    Last Post: 12-02-2007, 05:40 AM
  5. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM