Thread: Data Structures Program

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    166

    Data Structures Program

    Code:
    **        Pointers, Structures, Arrays, Strings, and Dynamic Allocation of Memory
    **
    **********************************************************************************
    
     This program provides antonyms to common words. An antonym is a word with
     the opposite meaning. For example, the antonym of happy is sad. The program is to
     look for a word and if found, report its antonym. If the word is not found, the
     program is to display an appropriate message.
    
     The input text file has a word and its antonym on each line, as it is shown below:
    
                   happy sad
                   ugly  attractive
                   nice  rude
                   cold  warmth
    
    ****************************************
    **
    **  Written By: 
    **              // <-- write your name here
    **
    **  Date: 6/12/2012        // <-- write the date here
    ***************************************************************************/
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    //#include <crtdbg.h>
    
    #define FILENAME "antonyms_0.txt"
    
    typedef struct
    {
       char *word;
       char *antonym;
    } PAIR;
    
    typedef struct
    {
       int   size; // number of words
       int   len;  // length of the longest word
       PAIR *pair;
    } LIST;
    
    
    LIST *createList(int num);
    LIST *getWords( char *fileName );
    char *allocateString( char *inString );
    void  readPair(FILE *fpWord, PAIR *pair, PAIR *revPair);
    void  insertPair(LIST *list, PAIR pair);
    void printTable(LIST *list);
    int binarySearch(LIST *list, char *target);
    char searchManager(LIST *list);
    void freeMemory(LIST *list);
    void printInfo (void);
    void printEnd (void);
    
    int main (void)
    {
       LIST *list;
       PAIR *pair;
       printInfo ();
    
       list = getWords(FILENAME);
       printTable(list);
       searchManager(list);
       freeMemory(list);
      // printf( _CrtDumpMemoryLeaks() ? "Memory Leak\n" : "No Memory Leak\n");
       printEnd ();
       return 0;
    
    }// main
    /* =================================================================================
    STUDENT - write your code below
    ================================================================================= */
    void printTable(LIST *list)
    {
       int i;
       char fmt[20];
       int max = (list->len) -1;
           for(i = 0; i <= max; i++)
           {
                   printf("=");
           }
           printf(" ");
           for(i = 0; i <= max; i++)
           {
                   printf("=");
           }
           printf("\n%10s %-10s\n", "Word", "Antonym");//formatting
           for(i = 0; i <= max; i++)
           {
                   printf("=");
           }
           printf(" ");
           for(i = 0; i <= max; i++)
           {
                   printf("=");
           }
           printf("\n");
           for(i = 0; i < list->size; i++)
           {
                   printf("%10s %-10s\n", list-> pair[i]);//formatting
    
           }
           for(i = 0; i <= max; i++)
           {
                   printf("=");
           }
           printf(" ");
           for(i = 0; i <= max; i++)
           {
                   printf("=");
           }
    
           printf("\n");
    return;
    }
    
    int binarySearch(LIST *list, char *target)
    {
    
       int first, mid, last;
       int result;
       int locn = -1;
    
           first = 0;
           last = (list->size) -1;
           mid = (list->size) / 2;
    
           while(first <= last && locn == -1 )
           {
                   mid = (first + last) / 2;
                   result = strcmp(list ->pair[mid].word, target);
                           if(result > 0){
                           last = mid - 1;
                           }
                                   else if( result < 0){
                                   first = mid + 1;
                                   }
                   else return mid;
    
           }
      return -1;
    }
    char searchManager(LIST *list)
    {
    
       char terminate[5] = "QUIT";
       int quit = 1;
       char *target;
       int locn;
           if(!(target = malloc(30 * sizeof(char)))){
                   printf("Not enough memory available!\n");
                   exit(100);
           }
           do
           {
                   printf("Which word would you like to search for? (Enter 'QUIT' to quit)\n");
                   scanf("%s", target);
                   quit = strcmp(target, terminate) == 0;
                           if(!quit)
                           {
                           locn = binarySearch(list, target);
                                   if(locn != -1)
                                   {
                                           printf("Your word: %s\nIt's antonym: %s\n", list->pair[locn]);
                                   }
                                   else
                                   printf("Your word was not found.\n");
                           }
           }
           while(!quit);
    }
    
    void freeMemory(LIST *list)
    {
       int i;
           for(i = 0; i < list->size; i++){
                   free(list->pair[i].word);
                   free(list->pair[i].antonym);
           }
           free(list);
    
    return;
    }
    
    
    
    /* =================================================================================
    INSTRUCTOR
    ================================================================================= */
    /* ============================================================
           Prints information about the project.
              PRE  : nothing
              POST : info printed
    */
    void printInfo (void)
    {
           printf("\n\n\t\tPointers, \n\n\t\tStructures, \n\n\t\tArrays, "
                      "\n\n\t\tStrings, and\n\n\t\tDynamic Allocation of Memory\n\n");
           printf("\tThis program provides antonyms to common words.\n");
       putchar('\n');
    
           return;
    
    } // printInfo
    
    /* ============================================================
           Prints a farewell message.
              PRE  : nothing.
              POST : farewell message printed
    */
    void printEnd (void)
    {
           printf("\n\t\tThank you for using the program,"
                      "\n\t\tHave a great day!\n");
    
           return;
    
    } // printEnd
    /* ============================================================
       Creates a sorted list of structures containing pointers
           to words and their antonyms.
       Pre:  fileName - the name of the input file
       Post: pointer to the list of structures
    */
    LIST *getWords( char *fileName )
    {
       FILE *fpWord;
           LIST *list;
           PAIR  pair, revPair;
           int   i, num;
           int len;
           // open the input file
       fpWord = fopen (fileName, "r");
       if (!fpWord)
           printf ("Error opening %s!\n", fileName), exit (101);
    
           // read the number of pairs
       fscanf(fpWord, "%d", &num);
           list = createList(num);
    
           // read the first pair
       readPair(fpWord, &pair, &revPair);
    
           len = strlen(pair.word);
           if(len > list-> len)
                   list-> len = len;
    
           len = strlen(pair.antonym);
           if(len > list-> len)
                   list-> len = len;
    
           // insert the first pair
           if( strcmp(pair.word, pair.antonym) < 0 ){
                   list->pair[0] = pair;
                   list->pair[1] = revPair;
           }
           else{
                   list->pair[0] = revPair;
                   list->pair[1] = pair;
           }
           list->size = 2;  // the first pair inserted: list has two words
    
           for( i = 1; i < num; i++ ){
           //find the length of the longest word
                   len = strlen(pair.word);
                   if(len > list-> len)
                           list-> len = len;
                   len = strlen(pair.antonym);
                   if(len > list-> len)
                           list-> len = len;
    
                   // read and insert the rest of the pairs
                   readPair(fpWord, &pair, &revPair);
                   insertPair(list, pair);
                   insertPair(list, revPair);
    
       }
    
           fclose(fpWord);
       return list;
    
    } // getWords
    
    /* ============================================================
       Allocates the header of the list and the list of pointers
           to words and their antonyms.
       Pre:  num - number of pairs
       Post: list - empty
    */
    LIST *createList(int num)
    {
           LIST *list;
    
       // allocate the header of the list
           list = (LIST *)malloc(sizeof(LIST));
       if (!list)
           printf ("Error allocating the header of the list!\n"), exit (102);
    
           // allocate the list of pointers to words and their antonyms
           list->pair = (PAIR *) calloc(2 * num, sizeof(PAIR));
       if (!list)
           printf ("Error allocating the list of words and their antonyms!\n"), exit (103);
       list->size = 0; // empty list
    
           return list;
    }// createList
    
    
    /* ============================================================
       Reads a pair of words and prepares them for insetions
       Pre:  fpWord
       Post: pair, revPair
    */
    void  readPair(FILE *fpWord, PAIR *pair, PAIR *revPair)
    {
       char  tempWord [100];
           char  tempAntonym [100];
    
           fscanf(fpWord, "%s %s", tempWord, tempAntonym);
           pair->word = allocateString(tempWord);
           pair->antonym = allocateString(tempAntonym);
           revPair->word = pair->antonym;
           revPair->antonym = pair->word;
    
           return;
    }// readPair
    
    /* ============================================================
       Inserts a word into a sorded list of words
       Pre:  list word
       Post: list updated
    */
    void  insertPair(LIST *list, PAIR pair)
    {
           int curr = list->size;
           int i;
    
       i = curr - 1;
           while ( i >= 0 && strcmp(pair.word, list->pair[i].word) < 0 ){
                   list->pair[i+1] = list->pair[i];
                   i--;
           }
           list->pair[i+1] = pair;
           list->size++;
    
           return;
    }// insertPair
    
    /* ============================================================
       Creates a dynamically allocated string with the same contents
           as the input string
       Pre:  inString - input string
       Post: outString - dynamically allocated
    */
    char *allocateString( char *inString )
    {
    
       char *outString;
       int   stringSize;
    
       stringSize = strlen( inString ) + 1;
       outString = (char *) calloc (stringSize, sizeof (char));
       if ( outString == NULL)
           printf ("ERROR, not enough memory!!!\a\n"), exit (103);
       strcpy (outString, inString);
    
       return outString;
    
    }// allocateString
    -Ok,so this is my pretty much finished program.
    Here are some concerns I have that I need tips on:
    -For the part where I print the "=" to format my table, is there an easier and simpler way to do it, or am I doing it fine?
    -I am not sure if I managed to free all the memory... I wasn't sure how to free PAIR. Is there anything else I need to free? And how?

    -If you see anything else that could be improved, please let me know as well.
    Thank you for your time!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    > -For the part where I print the "=" to format my table, is there an easier and simpler way to do it, or am I doing it fine?
    - A small function perhaps?
    - write each one on one line as for(i = 0; i <= max; i++) printf("=");
    - allocate a temp buffer, fill it with '=' and a \0, then just printf("%s",temp); as you need it
    Just experiment with different ideas.

    > -I am not sure if I managed to free all the memory... I wasn't sure how to free PAIR. Is there anything else I need to free? And how?
    Look at createList(), what else does it allocate?
    Look at other functions, do they allocate and not free memory?

    Are you using visual studio? If so, just uncomment the crtdbg lines.

    > outString = (char *) calloc (stringSize, sizeof (char));
    > if ( outString == NULL)
    > printf ("ERROR, not enough memory!!!\a\n"), exit (103);
    For tutor code, this is pretty awful.
    - casting the result of calloc (you're not compiling this C code with a C++ compiler are you?)
    - using calloc to begin with, when the whole memory is just going to get overwritten
    - abuse of the comma operator to save using braces
    - non-standard exit codes.
    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.

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    505
    The input doesn't contain a length field. So you need to either pass through the file counting the lines, then pass through a second time, or you need to grwo the list with realloc(). Then if you're using a binary search you need to sort it with qsort().

    Then you need to free the words, the pair list, and the list structure. Call the function something like "destroylist".
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    In binarySearch, you never modify the value of the locn variable, so what's the point of it?
    Also, like 129 is redundant due to line 133.
    Can you please fix your formatting?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Registered User
    Join Date
    Jan 2012
    Posts
    166
    Quote Originally Posted by Salem View Post
    > -For the part where I print the "=" to format my table, is there an easier and simpler way to do it, or am I doing it fine?
    - A small function perhaps?
    - write each one on one line as for(i = 0; i <= max; i++) printf("=");
    - allocate a temp buffer, fill it with '=' and a \0, then just printf("%s",temp); as you need it
    Just experiment with different ideas.

    > -I am not sure if I managed to free all the memory... I wasn't sure how to free PAIR. Is there anything else I need to free? And how?
    Look at createList(), what else does it allocate?
    Look at other functions, do they allocate and not free memory?


    Are you using visual studio? If so, just uncomment the crtdbg lines.
    No, I am doing this in Unix and compiling with gcc. Thats why its commented out. I'm supposed to use Valgrind, but I'm not quit sure how to interpret what it tells me.
    > outString = (char *) calloc (stringSize, sizeof (char));
    > if ( outString == NULL)
    > printf ("ERROR, not enough memory!!!\a\n"), exit (103);
    For tutor code, this is pretty awful.
    - casting the result of calloc (you're not compiling this C code with a C++ compiler are you?)
    - using calloc to begin with, when the whole memory is just going to get overwritten
    - abuse of the comma operator to save using braces
    - non-standard exit codes.
    -No, I am doing this in Unix and compiling with gcc. Thats why its commented out. I'm supposed to use Valgrind, but I'm not quit sure how to interpret what it tells me.
    -That code was actually written by the teacher. Some of the stuff in the program was. We are supposed to create more functions to add to it. So I'll probably leave that piece of code alone since its hers and I can't get marked down for it.

  6. #6
    Registered User
    Join Date
    Jan 2012
    Posts
    166
    Quote Originally Posted by Malcolm McLean View Post
    The input doesn't contain a length field. So you need to either pass through the file counting the lines, then pass through a second time, or you need to grwo the list with realloc(). Then if you're using a binary search you need to sort it with qsort().

    Then you need to free the words, the pair list, and the list structure. Call the function something like "destroylist".
    The input files state the number of lines of the file on the very first line.

  7. #7
    Registered User
    Join Date
    Jan 2012
    Posts
    166
    Quote Originally Posted by iMalc View Post
    In binarySearch, you never modify the value of the locn variable, so what's the point of it?
    Also, like 129 is redundant due to line 133.
    Can you please fix your formatting?
    Ok, I got rid of locn in binary search. For some reason I thought I needed it to be able to exit my while loop, but I guess not. I got rid of the duplicate lines as well. What do you mean by fix my formatting? I know I'm usually bad at indenting, but I tried hard and thought I did a pretty good job... Is it hard to read again?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. data structures
    By kiros88 in forum C Programming
    Replies: 8
    Last Post: 09-18-2009, 05:48 PM
  2. Need some help regarding data structures
    By Afrinux in forum C Programming
    Replies: 15
    Last Post: 01-28-2006, 05:19 AM
  3. Replies: 2
    Last Post: 06-16-2005, 10:03 AM
  4. data structures
    By hawkins786 in forum C++ Programming
    Replies: 1
    Last Post: 05-12-2005, 03:42 PM
  5. What is wrong with this program(data structures)
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 06-06-2002, 12:55 PM