Thread: C programming-Linked list problem

  1. #1
    Registered User
    Join Date
    May 2005
    Posts
    12

    C programming-Linked list problem

    Hi
    i am having an assignment about link list and i have alot of troubles understanding them. so i would to ask for your help.
    any contribution is great appreciate.

    here is the assignment spec

    "The European Commission has just announced an agreement whereby English will be the
    official language of the EU rather than German, which was the other possibility. As part of
    the negotiations, Her Majesty's Government conceded that English spelling had some room
    for improvement and has accepted a 5 year phase-in plan that would be known as
    "EuroEnglish": --
    In the first year, "s" will replace the soft "c". Sertainly, this will make the sivil sevants jump
    with joy. The hard "c" will be dropped in favor of the "k". This should klear up konfusion and
    keyboards kan have one less letter.
    There will be growing publik enthusiasm in the sekond year, when the troublesome "ph" will
    be replaced with the "f". This will make words like "fotograf" 20% shorter.
    In the 3rd year, publik akseptanse of the new spelling kan be expekted to reach the stage
    where more komplikated changes are possible. Governments will enkorage the removal of
    double letters, which have always ben a deterent to akurate speling. Also, al wil agre that the
    horible mes of the silent "e"'s in the language is disgraceful, and they should go away.
    By the 4th yar, peopl wil be reseptiv to steps such as replasing "th" with "z" and "w" with "v".
    During ze fifz year, ze unesesary "o" kan be dropd from vords kontaning "ou" and similar
    changes vud of kors be aplid to ozer kombinations of leters.
    After zis fifz yer, ve vil hav a reli sensibl riten styl. Zer vil be no mor trubls or difikultis and
    evrivun vil find it ezi tu understand ech ozer.
    ZE DREM VIL FINALI KUM TRU!!
    Program Action
    1. Your program will get the name of the file containing the English to be converted as a
    command line argument.
    2. It will then read the file and build up the English message, character by character, in a
    linked list. Each node in the list will contain a single character.
    3. You will then apply the following rules to the message contained in the link list. These
    rules will convert the English to Euro-English.
    Replace all ‘c’ with ‘s’ if followed the characters ‘e’, ‘i’ or ‘y’, otherwise replace with
    ‘k’.
    Replace all instances of ‘w’ with ‘v’.
    Replace all instances of “ph” with the character ‘f’.
    Replace all double characters with a single instance of the character.
    If a word is more than 3 characters long and ends with an ‘e’ then this can be
    removed.
    Replace all instances of “th” with ‘z’.
    Replace all instances of “ou” with ‘u’.
    Replace all instances of “ea” with ‘e’.
    If a word ends with “ed” then replace it with ‘d’.
    Make sure with all of these changes that you keep the correct case.
    4. As a final step, the program should then correctly free up all the memory used in the
    linked list.
    For example, the output of the program might would look like
    Here is a message from an important visitor:
    "Greetings, earthlings, I have come to rule you!"
    Hello, Mother, I can't talk right now,
    I am being harangued by a little green thingy.
    Her is a mesag from an important visitor:
    "Gretings, erzlings, I have kom to rul yu!"
    Helo, Mozer, I kan't talk right nov,
    I am being harangud by a litl gren zingy.
    Details
    While there are other data structures that would work, you must implement a “linked list
    chars”. Do not use arrays for this. See assessment section.
    A ‘word’ is defined as a string of alphanumeric characters that is preceded by a space or
    punctuation character or no character and followed by a space or punctuation character or no
    character.

    Here is my code

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    #define SIZE 120
    
    struct charRecord
    {
    
       char letter;
       struct charRecord *next;
    
    };
    typedef struct charRecord charNode;
    
    FILE* openFile(char *filename, char *mode);
    
    void loadChar(char *filename, charNode **start);
    
    void insertCharToList(charNode **start,char *letter);
    
    void printList ( charNode *start);
    
    void freeList(charNode **start);
    
    charNode* newNode(char letter);
    
    int main(int argc, char *argv[])
    {
    
       charNode *start =NULL;
       char line[SIZE];
     
       /* Check command line arguments */
    
       if (argc != 2)
       {
    
          printf("\nERROR - Incorrect number of arguments\n");
          return 0;
    
       }
    
       loadChar(argv[1], &start);
       printList(start);
       freeList(&start);
    
       printf("i am in main");
    
     return 0;
    
    }
    
    /* 
    Your program will get name of the file containning the english
    to be converted as a command line argument
    */
    
    FILE* openFile(char *filename, char *mode)
    
    {
       /* open a FILE stream to filename with given mode */
    
       FILE *file = fopen(filename, mode);
    
       if (file == NULL)
       {
    
          printf("ERROR - Unable to open file %s\n", filename);
          exit(0);
    
       }
    
       return file;
    }
    
    /* it will tren read the file and build up the English message,
    character by character in a SINGLE linked list.
    Each Node in the list will contain a single chracter.
    */
    
    void loadChar(char *filename, charNode **start)
    {
    
       /* load emplyee records and add to linked list */
    
       char line[SIZE]; //, wordends[] = " \t\r\n\",;:~!#%^*()=+[]{}\\|<>?/";
    
       FILE *fin = openFile(filename, "r");
       int i;
       
       while (fgets(line, SIZE, fin) != NULL)
       {
    
    
       }
    
       if (!feof(fin))
       {
    
          printf("ERROR - unable to read lines in %s\n", filename);
          exit(0);
    
       }
       fclose(fin);
    
    }
    
    void insertCharToList(charNode **start,char *letter)
    {
    
       /* insert word into list in alphabetical order */
       printf(" i am at insertTolist \n");
       int i;
       char line[SIZE];
       charNode *temp,*prev, *loc;
    
       for (i=0; i<SIZE; i++)
       {
    
          temp = newNode(line[i]);
    
       }
    
    }
    
    
    /*
    you will need to apply the rules to the message contained in the link list.
    */
    
    int applyRules()
    {
    
     // rule 1  replace all instances of 'w' with 'v'
     
     // rule 2: replace all double characters with a single instance of the chracter.
    
     //rule 3: replace all instances of 'ph' with teh chracter 'f'
     
     //rule 4: Replace all instances of the 'th' with 'z'.
     
     //rule 5: Replace all instances of 'ou' with 'u'.
    
     //rule 6: Replace all intances of 'ea' with 'e'.
     
     //rule 7: Replace all 'c' with 's' if followed by the characters 'e','i' or 'y', otherwise replace with 'k'.
     
     //rule 8: if a word is more than 3 characters long and ends with an 'e' then this can be removed.
    
     // rule 9: If a word ends with "ed" then replace with "d".
    
    
    
    }
    
    /* the program should print out the the Euro english */
    void printList ( charNode *start)
    {
    
         /*
         print out the contents of the linked list
         start with the first item added
         */
       printf("i am printing\n");
       while (start != NULL)
       {
          printf("%c",start->letter);
          start = start->next;
    
       }
       printf("\n");
    }
    
    
    /* the programm should free all the memory used in the linked list */
    
    void freeList(charNode **start)
    {
    
       /* free up all word records in linked list */
    
      charNode *temp;
    
       while (*start != NULL)
       {
          temp = *start;
          *start = temp->next;
          free(temp);
       }
    
    }
    
    /* the program allocate memory for the linked list */
    
    charNode* newNode(char letter)
    {
    
       /* dynamicaly allocate memory for an charNode
          make sure it is initialised correctly
       */
    
       charNode *temp= (charNode *) malloc(sizeof(charNode));
    
       if (temp == NULL)
       {
          printf("WARNING - Memory allocation error\n");
          exit(EXIT_FAILURE);
       }
    
       temp->letter = letter;
       temp->next = NULL;
    
       return temp;
    
    }
    i am having problems of aplying the rules
    and how to load up the files character by character and put them into a single link list.........
    if you have any reference or anything that can help with my assignment please tell me
    thanz for your help

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    fgetc will read one character at a time. Simply create a function which creates a new node and sticks one character into it. Then to apply your rules, just run through your linked list and make your changes by either changing the value of the character in the node in question, or by removing nodes, or whatever is required.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    May 2005
    Posts
    12
    hi
    i am able to read chacracers from a file
    can you please show me to put them into a link list
    give me some examples
    thank you
    Code:
    #include <stdio.h>
    
    main()
    {
      int c;				/* Character read from the file.	*/
      FILE *ptr;			/* Pointer to the file. FILE is a
    				   structure  defined in <stdio.h>	*/
    
    				/* Open the file - no error checking done */
      ptr = fopen("data1.txt","r");
    				/* Read one character at a time, checking
    				   for the End of File. EOF is defined 
    				   in <stdio.h>  as -1 			*/
      while ((c = fgetc(ptr)) != EOF)
      {
        printf("%c",c);		/* O/P the character to the screen	*/
      }
    
      fclose(ptr);			/* Close the file.			*/
    }

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I'd suggest you read the linked list tutorials in the FAQ. Basically you'll want something like:
    Code:
    int c;
    while( (c = fgetc( fp )) != EOF )
    {
        allocate a new node
        put c into it
        add it to the end of the list
    }
    At any rate, if you don't know how to make a linked list, the tutorials will show you. Click the nice shiny FAQ link near the top of the page.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    May 2005
    Posts
    12
    hi
    i am successfully read from a file and display the characters from it
    however i want to apply soime rules to the link list
    can someone give me some examples of how doing it?

    here is my code
    Code:
      /* Pointer to the file. FILE is a  structure  defined in <stdio.h>	*/

  6. #6
    Registered User
    Join Date
    May 2005
    Posts
    12
    sorry i forgot to paste the whole doc
    hi
    i am successfully read from a file and display the characters from it
    however i want to apply soime rules to the link list
    can someone give me some examples of how doing it?

    here is my code
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    #define SIZE 120
    
    struct charRecord
    {
       char letter;
       struct charRecord *nextNode;
    };
    typedef struct charRecord charNode;
    
    FILE* openFile(char *filename, char *mode);
    void loadChar(char *filename, charNode **start);
    void printList ( charNode *start);
    void freeList(charNode **start);
    charNode* createNode(char nodeLetter);
    
    int main(int argc, char *argv[])
    {
       charNode *start =NULL;
       char line[SIZE];
    
       /* Check command line arguments */
       if (argc != 2)
       {
          printf("\nERROR - Incorrect number of arguments\n");
          return 0;
       }
    
       loadChar(argv[1], &start);
       printList(start);
       freeList(&start);
    
     return 0;
    }
    
    /*
    Your program will get name of the file containning the english
    to be converted as a command line argument
    */
    
    FILE* openFile(char *filename, char *mode)
    {
       /* open a FILE stream to filename with given mode */
    
       FILE *file = fopen(filename, mode);
    
       if (file == NULL)
       {
          printf("ERROR - Unable to open file %s\n", filename);
          exit(0);
       }
    
       return file;
    }
    
    /* it will tren read the file and build up the English message,
    character by character in a SINGLE linked list.
    Each Node in the list will contain a single chracter.
    */
    
    void loadChar(char *filename, charNode **start)
    {
        char c;
       /* Pointer to the file. FILE is a  structure  defined in <stdio.h>	*/
       charNode *temp, *tail = *start;
    
       /* Open the file - no error checking done */
       FILE *fin = openFile(filename, "r");   
       
      /* Read one character at a time, checking */
      while ((c = fgetc(fin)) != EOF)
      {
        temp = createNode(c) ;
        if(tail == NULL)
        {
           *start = tail = temp ;
        }
        else
        {
          tail->nextNode = temp;
          tail = temp;
        }
    
      }
    
       if (!feof(fin))
       {
          printf("ERROR - unable to read lines in %s\n", filename);
          exit(0);
       }
       fclose(fin);
    }
    
    
    /*
    you will need to apply the rules to the message contained in the link list.
    */
    int applyRules()
    {
     // rule 1  replace all instances of 'w' with 'v'  
    
     // rule 2: replace all double characters with a single instance of the chracter.
    
     //rule 3: replace all instances of 'ph' with teh chracter 'f'
    
     //rule 4: Replace all instances of the 'th' with 'z'.
    
     //rule 5: Replace all instances of 'ou' with 'u'.
    
     //rule 6: Replace all intances of 'ea' with 'e'.
    
     //rule 7: Replace all 'c' with 's' if followed by the characters 'e','i' or 'y', otherwise replace with 'k'.
    
     //rule 8: if a word is more than 3 characters long and ends with an 'e' then this can be removed.
    
     // rule 9: If a word ends with "ed" then replace with "d".
    
    
    }
    
    /* the program should print out the the Euro english */
    void printList ( charNode *start)
    {
         /*
         print out the contents of the linked list
         start with the first item added
         */
      // printf("i am printing\n");
       while (start != NULL)
       {
          printf("%c",start->letter);
          start = start->nextNode;
    
       }
       printf("\n");
    }
    
    
    /* the programm should free all the memory used in the linked list */
    
    void freeList(charNode **start)
    {
    
       /* free up all word records in linked list */
    
      charNode *temp;
    
       while (*start != NULL)
       {
          temp = *start;
          *start = temp->nextNode;
          free(temp);
       }
    
    }
    
    /* the program allocate memory for the linked list */
    
    charNode* createNode(char nodeLetter)
    {
    
       /* dynamicaly allocate memory for an charNode
          make sure it is initialised correctly
       */
    
       charNode *temp= (charNode *) malloc(sizeof(charNode));
    
       if (temp == NULL)
       {
          printf("WARNING - Memory allocation error\n");
          exit(EXIT_FAILURE);
       }
    
       temp->letter = nodeLetter;
       temp->nextNode = NULL;
    
       return temp;
    
    }

  7. #7
    Registered User
    Join Date
    May 2005
    Posts
    12
    hi
    i just want to verified the objectives of my program.
    my programs needs to read from a file character by character then put them into a single link list
    after a link list of characters is created, then i have to apply some rules, that is i have to replace some letters in the link list and display the output on the screen.
    I DO NOT NEED TO EDIT OR MAKE CHANGE TO THE ORIGINAL FILE.
    ALL I NEED IS TO DISPLAY THE OUTPUT

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Why is apply_rules() declared as int? Where do you call apply_rules() from?

    For simple replacements like "replace all 'w's with 'v's" you would scroll through your linked list, like you did in freeList(), and check to see if the char stored is a w. If it is, replace it with a 'v'.

    For replacements like "replace 'ph' with 'f'" you would again scroll through your list, checking for 'p's. When you find a 'p', see if pointer->next->letter is an 'h'. If it is, delete the next node in the list (the 'h'), and change the 'p' to an 'f'.

    I hope this helps.

    dwk

  9. #9
    Registered User
    Join Date
    May 2005
    Posts
    12
    Hi
    i tried to apply the rules hoever it gives me the errors
    euro.c: In function `applyRules':
    euro.c:109: warning: comparison between pointer and integer
    euro.c:111: warning: assignment makes pointer from integer without a cast
    can you plese have me what is going on and please show me to fix this?
    Code:
    void applyRules(charNode **start)
    {
     charNode *temp;
       while (*start != NULL)
       {
          temp = *start;
          *start = temp->nextNode;
          if(temp == 'w')
          {
            temp = 'v';
          }    
       }
    }

  10. #10
    Registered User
    Join Date
    May 2005
    Posts
    12
    hi
    i am able to replace with a w now..
    however now i want to replace double characters with a single one
    for instance
    message will become mesage
    here is my code
    Code:
    void applyRules(charNode **start)
    {
    
       charNode *temp;
    
       temp = *start;
    
       while (temp != NULL)
       {      
          if (temp->letter == 'w')
          {
             temp->letter ='v';
          }
          if(temp->letter == temp->nextNode->letter)
          {
             free(temp->letter);
          } 
          temp = temp->nextNode;
               
       }
    i got the following errors
    Code:
    bash-3.00$ gcc -Wall -Werror euro.c
    euro.c: In function `applyRules':
    euro.c:119: warning: passing arg 1 of `free' makes pointer from integer without a cast
    can someone please help me out
    thanz

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well look at what the error message is telling you.
    It's making a pointer from an integer - so why does the compiler think it's an integer?

    > free(temp->letter);
    You probably meant
    free(temp);

    However, this leads to another trap.
    Code:
          if(temp->letter == temp->nextNode->letter)
          {
             free(temp);
          } 
          temp = temp->nextNode;
    If you do free(temp), then temp = temp->nextNode becomes an invalid operation.
    So you should use another variable to help you step over the node you're about to delete.
    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 2005
    Posts
    12
    can you please demonstrate me how to set another variable to step over the node you're about to delete??
    i tried to declare temp2 as another variable that hold temp->nextNode->letter.
    then i try to free temp2.
    however it doesnt see to work
    noting happen
    Code:
    void applyRules(charNode **start)
    {
    
       charNode *temp, *temp2;
    
       temp = *start;
     temp2 =temp=*start;
       while (temp != NULL)
       {      
            if(temp->letter == temp->nextNode->letter)
          {
              temp2=temp->nextNode->letter 
             free(temp2);
          } 
          temp = temp->nextNode;
               
       }

  13. #13
    Registered User
    Join Date
    May 2005
    Posts
    12
    hi
    one of my friend helpme out with this however he use NULL for nextNOde
    like temp->nextNode->letter = NULL;
    somehow i can compile at my uni computer
    when i go hoem and use cgywin
    it gives me errors like:
    "assignment makes integer from pointer without a cast"
    can someone please explain to me why?

    plus i want to use ctype.h libraries
    so that i only work with characters not digits, thats mean i will ignore digits in the file
    because currently my file delete double digits
    how do i use isalpha(c) and !isdigit(c) in my while loop
    i really need help
    thanz for peopel who help me so much
    really appreciate it

    Code:
    void applyRules(charNode **start)
    {
    
       charNode *temp;
    
       temp = *start;
    
       while (temp != NULL && temp->nextNode != NULL )
       {
          if(temp->letter== 'w')
          {
             temp->letter ='v';
          }
          else if(temp->letter== temp->nextNode->letter)
          {
             temp->nextNode->letter =NULL;
          }
          else if(temp->letter== 'p' && temp->nextNode->letter == 'h')
          {
             temp->letter ='f';
             temp->nextNode->letter =NULL;
          }
          else if(temp->letter== 't' && temp->nextNode->letter == 'h')
          {
             temp->letter ='z';
             temp->nextNode->letter =NULL;
          }
          else if(temp->letter== 'o' && temp->nextNode->letter == 'u')
          {
             temp->letter ='u';
             temp->nextNode->letter =NULL;
          }
          else if(temp->letter== 'e' && temp->nextNode->letter == 'a')
          {
             temp->letter ='e';
             temp->nextNode->letter = NULL;
          }
          else if(temp->letter== 'c')
          {
             if(temp->letter== 'c' && (temp->nextNode->letter == 'e'
                                  || temp->nextNode->letter == 'i'
                                  || temp->nextNode->letter == 'y'))
             {
                temp->letter ='s';
             }
             else 
             {
                temp->letter ='k';
             }
          }
          else if( temp->letter== 'e' && temp->nextNode->letter==' ')
          {
             temp->letter=NULL;
          }
          else if(temp->letter== 'e' && temp->nextNode->letter == 'd'
                                     && temp->nextNode->nextNode->letter == ' ')
          {
             temp->letter = 'd';
             temp->nextNode->letter = NULL;
          }
    
          temp = temp->nextNode;
       }
    }

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well you already managed one variable, why not two?
    Code:
          if(temp->letter == temp->nextNode->letter)
          {
             /* delete the current node */
             charNode *delnode = temp;
             temp = temp->nextNode;
             if ( delnode == *start ) {
                /* we just deleted the node at the head of the list */
                /* so update the list to point to the new head */
                *start = temp;
             }
             /* finally, delete the node we don't want */
             free(delnode);
          }
          else
          {
             temp = temp->nextNode;
          }
    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.

  15. #15
    Registered User
    Join Date
    May 2005
    Posts
    12
    Code:
    void applyRulesTwo(charNode **start)
    {
    
       charNode *temp;
       temp = *start;
       while (temp != NULL && temp->nextNode != NULL )
       {
          if(temp->letter == temp->nextNode->letter)
          {
             /* delete the current node */
             charNode *delnode = temp;
             temp = temp->nextNode;
             if ( delnode == *start ) {
                /* we just deleted the node at the head of the list */
                /* so update the list to point to the new head */
                *start = temp;
             }
             /* finally, delete the node we don't want */
             free(delnode);
          }
          else
          {
             temp = temp->nextNode;
          }
       }
    }
    i dont know why your code doesnt seem to work
    it does not delete any double chars.....
    thanz for you help...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help sorting a linked list. Beginner
    By scarlet00014 in forum C Programming
    Replies: 1
    Last Post: 09-27-2008, 06:16 PM
  2. singly linked circular list
    By DarkDot in forum C++ Programming
    Replies: 0
    Last Post: 04-24-2007, 08:55 PM
  3. Replies: 6
    Last Post: 03-02-2005, 02:45 AM
  4. Linked list with two class types within template.
    By SilasP in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2002, 06:13 AM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM