Thread: In desperate need of help with string search and sort functions!!!

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    5

    In desperate need of help with string search and sort functions!!!

    I am in my last day of my C programming class, and I have been so frustrated with this code that I have put it off over and over again. I have finally gave in and decided to post it on the boards. Please leave any advice and tips so that I might be able to finish this tonight! The first function displays the word, grammar type, and quantity found in file, the second function sorts based on word, grammar type, and quantity found in file. The final function, which I was having the most problems with, searches the file for the words from the struct. Any help would be greatly appreciated!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    # define MAX_WORD_SIZE 15
    # define NUMRECORDS 23
    # define TRUE 1
    # define FALSE 0
    
    enum columns { WORD, GRAMMAR, QUANTITY };
    
    typedef struct 
    {
       char word[MAX_WORD_SIZE];
       enum { noun, verb, adverb, article, pronoun, adjective } type;
       int numTimesAppear;
    } record;
    
    
    record wordlist[NUMRECORDS] = 
    	{
    		  { "the", article, 0 }
    		, { "their", pronoun, 0 }
    		, { "a", article, 0 }
    		, { "difficult", adjective, 0 }
    		, { "run", verb, 0 }
    		, { "you", pronoun, 0 }
    		, { "game", noun, 0 }
    		, { "quickly", adverb, 0 }
    		, { "name", noun, 0 }
    		, { "he", pronoun, 0 }
    		, { "team", noun, 0 }
    		, { "quietly", adverb, 0 }
    		, { "president", noun, 0 }
    		, { "it", pronoun, 0 }
    		, { "interest", noun, 0 }
    		, { "promptly", adverb, 0 }
    		, { "whom", pronoun, 0 }
    		, { "ball", noun, 0 }
    		, { "decide", verb, 0 }
    		, { "she", pronoun, 0 }
    		, { "land", noun, 0 }
    		, { "is", verb, 0 }
    		, { "of", article, 0 }
    	};
    
    int processFile( char fn[ ] );
    void printRecords( );
    void sortRecords( enum columns which );
    
    int main( int argc, char *argv[ ]  )
    { 
       if (  argc != 2 )
       { 
    	printf( "Usage: %s filename\n", argv[0] );
    	return -1;
       }
       if (  processFile( argv[1] ) < 0 )
       { 
    	printf( "Error on file: %s \n", argv[1] );
    	return -1;
       }
    
       printRecords( );
       sortRecords( WORD );
       printf( "\n====================================\n" );
       printf( "\n========Sorted by word==============\n" );
       printf( "\n====================================\n" );
       printRecords( );
    
       sortRecords( GRAMMAR );
       printf( "\n====================================\n" );
       printf( "\n========Sorted by type==============\n" );
       printf( "\n====================================\n" );
       printRecords( );
    
       sortRecords( QUANTITY );
       printf( "\n====================================\n" );
       printf( "\n=======Sorted by quantity===========\n" );
       printf( "\n====================================\n" );
       printRecords( );
    }
    
    void printRecords( )
    {
       printf( "\n           WORD\t      TYPE\t# APPEAR\n" );
       for( int i=0; i<NUMRECORDS; i++ )
       {
     	switch(wordlist[i].type)
     	{
     		case 0:
     			printf( "%15s\t noun \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 1:
     			printf( "%15s\t verb \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 2:
     			printf( "%15s\t adverb \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 3:
     			printf( "%15s\t article \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 4:
     			printf( "%15s\t pronoun \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 5:
     			printf( "%15s\t adjective \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     	}
       	//printf( "%15s\t%10s\t%3d\n", wordlist[i].word, grammar, wordlist[i].numTimesAppear );
       }
    }
    
    void sortRecords( enum columns which )
    {
    	record temp;
    	int wordcount=0;
    	record newwordlist[NUMRECORDS];
    	switch(which)
    	{
    		case 0:
    			for(int i=0; i<NUMRECORDS; i++)
    			{
    				
    			}
    			break;
    		case 1:
    			for(int j=0; j<6; j++)
    			{
    				for(int i=0; i<NUMRECORDS; i++)
    				{
    					if(wordlist[i].type==j)
    					{
    						newwordlist[wordcount]=wordlist[i];
    						wordcount++;
    					}
    				}
    			}
    			for(int i=0; i<NUMRECORDS; i++)
    			{
    				wordlist[i]=newwordlist[i];
    			}
    			break;
    		case 2:
    			for(int i=0; i<NUMRECORDS; i++)
    			{
    				if(wordlist[i].numTimesAppear<wordlist[i+1].numTimesAppear)
    				{
    					temp=wordlist[i];
    					wordlist[i]=wordlist[i+1];
    					wordlist[i+1]=wordlist[i];
    				}
    			}
    	}
    }
    
    int processFile( char fn[ ] )
    {
       FILE *file;
       char line[81];
       char query[MAX_WORD_SIZE];
       if ( (file = fopen( fn, "r" )) == NULL )
       {
    	return -2;
       }
       while( fgets(line, sizeof(line), file ) != NULL )
       {
       		for(int i=0; i<NUMRECORDS; i++)
       		{
       			for(int j=0; i<=strlen(line); )
    			{
       				while(line[j] != ' ')
       				{
       					query[j]=line[j];
       					j++;
       				}
       				if(strcmp(query, wordlist[i].word) == 0)
       				{
       					wordlist[i].numTimesAppear++;
       				}
       				j++;
    			}
       		}
       }
       fclose(file);
       return 0;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Your processFile() should be
    - for each line of the file
    -- for each word in the line
    --- search for word in wordlist
    ---- if word is in word list, increment count.

    You might find the strtok() function useful at breaking a line into words.
    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
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    This section should surely use the enum that you have declared in the type declaration above - otherwise you have a bug waiting to happen when someone decides to re-order the wordtypes so they are in alphabetical order (or some such).

    Code:
    switch(wordlist[i].type)
     	{
     		case 0:
     			printf( "%15s\t noun \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 1:
     			printf( "%15s\t verb \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 2:
     			printf( "%15s\t adverb \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 3:
     			printf( "%15s\t article \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 4:
     			printf( "%15s\t pronoun \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
     			break;
     		case 5:
     			printf( "%15s\t adjective \t%3d\n", wordlist[i].word, wordlist[i].numTimesAppear );
    Alternatively, move the enum declaration outside the struct, and then next to that, declare an array of strings "wtname" that have the names, then print "wtname[wordlist[i].type" as part of your output.

    --
    Mats

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    		case 0:
    			for(int i=0; i<NUMRECORDS; i++)
    			{
    				
    			}
    			break;
    I take it this means that you are not comparing and swapping the strings at all? You do know that "strcmp" returns a signed number that indicates whether the first string is lesser, equal or greater than the second string?

    Code:
    				if(wordlist[i].numTimesAppear<wordlist[i+1].numTimesAppear)
    				{
    					temp=wordlist[i];
    					wordlist[i]=wordlist[i+1];
    					wordlist[i+1]=wordlist[i];
    				}
    This looks a bit broken, doesn't it.

    And I suspect that you won't actually sort to the correct order. Consider this list of numbers that we want sorted as "biggest first":

    16
    13
    12
    14

    If we swap 14 and 12, it's got this order:
    16
    13
    14
    12

    So we haven't completed the sort, have we?

    --
    Mats

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  2. Big help in Astar search code...
    By alvifarooq in forum C++ Programming
    Replies: 6
    Last Post: 09-24-2004, 11:38 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Search and Sort functions for a stack..
    By blizeH in forum C++ Programming
    Replies: 7
    Last Post: 01-24-2003, 01:36 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM