Thread: Suggest another way or how can my code be improved

  1. #1
    Registered User
    Join Date
    Dec 2005
    Location
    Australia - Melbourne
    Posts
    63

    Suggest another way or how can my code be improved

    the program i've written counts the number of words in a string entered from the keyboard (it works).

    if someone could, please tell me if there is a better way to do it or how i can improve my code.

    Code:
    /*  header: # of words
        notes: this program counts the number of words in a string.
                - a word is a sequence of consecutive letters
    */
    
    #include <stdio.h>
    #include <string.h>
    
    int nwords(int, char []);
    int ctest(char, int);
    
    int main() {
        char line[100];
        // get string
        printf("Enter a string: ");
        fgets(line, sizeof(line), stdin);
        
        // get number of words
        printf("number of words is %d", nwords(strlen(line)-1, line));
        
        while (getchar() != '\n') ;
        
        return 0;
    }    
    
    /* name: words counter
       parameters: length = length of string, line[] = string array
       return: the number of words in string
       note: character excludes tab, space, return, and null
    */
    int nwords(int length, char line[]) {
        int x = 0;          // position of character in string- starts from 0
        int fchar;          // position of first character
        int lchar;          // position of last character
        int letters = 0;    // number of letters in sequence from fchar to lchar
        int words = 0;      // number of words counter
        
        /* in line if position of last consecutive character minus position of first character 
        plus 1 equals the number of letters in sequence the sequence of characters is a word. 
        example        : what happens                                               : word  
        hello          : fchar = 0; lchar = 4; letters = 5; lchar-fchar+1=letters     yes
         yes           : fchar = 1; lchar = 3; letters = 3; lchar-fchar+1=letters     yes
        hello yes      : fchar = 0; lchar = 4; letters = 5; lchar-fchar+1=letters     yes
                         fchar = 6; lchar = 8; letters = 3; lchar-fchar+1=letters     yes */
        
        for ( x; x < length; ++x) {
            if ( ctest(line[x], 3) ) {                // if it isn't a tab, space, return key and NULL
                fchar = x;                            // sets position of "first character"
                if ( ctest(line[x], 1) ) ++letters;   // if it is a letter, letter increments
                for ( x+1; x < length; ++x) {         // checks string after the "first character" 
                    if ( ctest(line[x+1], 2) ) {      // if it is a tab, space, return key or NULL, sets position of "last character" and break out of loop   
                        lchar = x;  
                    }    
                    else if ( ctest(line[x+1], 1) ) { // if it is a letter, letter increments and goes to top
                        ++letters;
                        continue;
                    }    
                    else continue;
                    break;                  
                }    
            }
            if (lchar-fchar + 1 == letters) ++words;  // if it is a word, word increments
            letters = 0;                              // reset letter to zero - important
        }
        return (words);
    }        
    
    /* name: character test
       parameters: character = a character, consider = a number (1-3)
       return: zero or 1
    */
    int ctest(char character, int consider) {
        switch (consider) {
            case 1:        // if it is a character
                if ((character >= 'a' && character <='z') || (character >= 'A' && character <='Z')) return 1;
                break;
            case 2:        // if it is a tab, space, return key or NULL
                if (character == '\t' || character == ' ' || character == '\n' || character == '\0') return 1;
                break;
            case 3:        // if it isn't a tab, space, return key and NULL
                if (character != '\t' && character != ' ' && character != '\n' && character != '\0') return 1;
                break;
        }
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195
    If you put your function defintions above main, you won't need to declare the functions. Ie, you could then omit the lines:

    Code:
    int nwords(int, char []);
    int ctest(char, int);
    Also, a least under ANSI, it is either

    int main(void)

    or

    int main(int argc, char **argv)

    NOT

    int main()


    Just my 2 cents
    Chad

  3. #3
    ex-DECcie
    Join Date
    Dec 2005
    Posts
    125
    As a matter of personal taste and convention, I use 'i' as the index in for loops, where you're using 'x'. Again, it's a matter of personal preference, but it is similar to way folks use 'foo' and 'bar' for example variables. No big deal at any rate....


    Also, you could use some of the "is" functions in your ctest function.
    They're declared in ctype.h. For example, isalpha() will tell you if it is a character. BTW, you are checking for a through z and A through Z, but don't forget that 0-9 are also characters.

    I haven't had coffee yet, but you might try something like:

    Code:
    if (isalpha(character))
        /* then it's a-z or A-Z or 0-9 */

    Just my 2 cents worth

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    isalpha does not check digits. Hence the 'alpha' portion of the function name. Perhaps you're thinking of isalnum?


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

  5. #5
    ex-DECcie
    Join Date
    Dec 2005
    Posts
    125
    Quote Originally Posted by quzah
    isalpha does not check digits. Hence the 'alpha' portion of the function name. Perhaps you're thinking of isalnum?


    Quzah.

    Oh, of course.

    Had not had coffee yet, and I touch type. Sometimes, my fingers betray me and type what THEY think and not what my non-caffeinated brain is thinking.

    Good catch. Most definitely isalnum().

  6. #6
    Registered User
    Join Date
    Dec 2005
    Location
    Australia - Melbourne
    Posts
    63
    thanks

    cdalten i know about the prototype bit but little about the second suggestion (i think i will start using int main(void))

    fgw_three i used x because it was the first thing that came to mind, also x is very commonly used when i do maths. i will use i maybe next time. thanks for the new function though (i don't know many currently).

    quzah thanks for the other function.

  7. #7
    Cached User mako's Avatar
    Join Date
    Dec 2005
    Location
    Germany.Stuttgart
    Posts
    69
    isdigit tests for digits obviouslt, alnum does both in one, and both functions are in ctype.h

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Proposal: Code colouring
    By Perspective in forum A Brief History of Cprogramming.com
    Replies: 28
    Last Post: 05-14-2007, 07:23 AM
  2. Values changing without reason?
    By subtled in forum C Programming
    Replies: 2
    Last Post: 04-19-2007, 10:20 AM
  3. Updated sound engine code
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 11-18-2004, 12:38 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. Replies: 4
    Last Post: 01-16-2002, 12:04 AM