Thread: my first semi useful program

  1. #16
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    this may be a little bit better way of implementing this....
    it's basically the same, but try to make your functions do one thing and one thing only. that's called cohesion. you should probably break it up even more (than i have)....like a function the prints "Typing tutor..."
    and then one that is the actual typing part of it....and then a function that grades it....although this program doesn't really need such cohesion, if you wanted to enhance it and make it bigger and better, then breaking it up into smaller pieces is the best way to plan for the future....or even the best way to build, manage, and think about any program....

    i typically try to make main have nothing but function calls...i think of main as the conducter of the program....


    Code:
    #include <stdio.h>
    #include <time.h>
    
    #define HOME "asdfghjkl;\'\""
    #define RANGE sizeof(HOME)-1
    #define LINES 2                //number of lines to type
    void fillstring(char *s,int error);
    int typestring(char *s,int *size);
    
    
    
    int main()
    { 
      char string[16];
      char *s;
      s = string;
      int do_again = 1;
      
      int er = 0;
      int *error;
      error = &er;
      
      c = getche();   
      while(c != 'Y' || c != 'y')
      {
           typestring(s, error);
            printf("try again (y/n)");
           c = getche();
      }   
      return 0;
    }
    
    void typestring(char *s,int *error)
    {
      char c;
      *error = 0;
      int line = 0;
      
      do
      {   
          fillstring(s,RANGE); 
          system("cls");
          printf("Typing Tutor 0.1\n");
          printf("Type the following lines:\n");
          printf("\n%s\n",s);
      
            do
            {
                    while((c = getch()) != *s)       
                         (*error)++;
                    printf("%c",c);
                    s++;
            }              
            while(*s);    
      
          line++;
      
          if(line == LINES)
              break;
      }        
      while(1);
      
      printf("\n");
      printf("\nYou typed %i characters wrong!\n",*error);
      if(*error > 5) printf("\nYou suck!");
     
      
    }
        
    void fillstring(char *s,int size)
    {
        int i;
        char home[] = HOME;
        
        srand((unsigned)time(NULL));
        
        for(i=0;i<16;i++)        //fill string with home row characters
        {
            *(s+i) = home[rand()%size];
          
            while(*(s+i) == *(s+i-1))          //this loop keeps letters from repeating
                  *(s+i) = home[rand()%size];
            
                                    
        }  
        *(s+16) = '\0';   
    }
    Last edited by misplaced; 10-04-2004 at 08:12 PM.

  2. #17
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Try turning on your compiler's warnings. For starters, you aren't including a required header. (getche) You'll also be warned that you should have some parenthesis around your loop check/assignment:
    Code:
    while(do_again = typestring(s,error));
    You also underrun your array here:
    Code:
    for(i=0;i<16;i++)        //fill string with home row characters
        {
            *(s+i) = home[rand()%size];
          
            while(*(s+i) == *(s+i-1))          //this loop keeps letters from repeating
    When s is the start of your array, and i is zero, then s - 1 is a BadThing(tm). You can check one past your array, but not one before it.

    That's what I noticed at a quick look. See if you can take care of all that, then try again.

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

  3. #18
    Registered User
    Join Date
    Nov 2003
    Posts
    28
    ok, i've made quite a few changes this time, I started from scratch this time and tried to make my program code look a little more neat. I also tried to bring each step down into their own functions, expecpt for the fillstring function. I'm learning more this way than I would in a week of studying the book

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <conio.h>
    
    #define HOME "asdfghjkl;:\'\""
    #define GROUPS 4
    
    
    char fillstring(char *string)
    {
        //this function constructs our string of random home row keys
        int x;
        int groups = GROUPS;
        strcpy(string,"\0"); //this makes strcat attach to start of string if 
                             //string already has a value
        
        char home[] = HOME;
        char temp[5];
        
        do
        {
            for(x=0;x<4;x++)
            {
                temp[x] = home[rand()%13];
                if(x>0)
                {
                    if(temp[x] == temp[x-1])
                        temp[x] = home[rand()%13];
                }        
            }            
            temp[4] = ' ';
            temp[5] = '\0';
        strcat(string,temp);   //hooks our groups of four together to build larger line 
                               //but still separated by a white space charcter
        }
        while(--groups);
        
        //remove the trailing whitespace
        string[19] = '\0';
           
    }
    
    void seedrand()
    {
        srand((unsigned)time(NULL));
    }
    
    int getinput(char *s)
    {
        char c;
        int error = 0;
        do
        {
            while((c = getch()) != *s)
            {
                error++;
            }    
            printf("%c",c);
            s++;
        }              
        while(*s);
        
        return error;
    }
    
    void startmsg(char *s)
    {
        printf("Typing Tutor 0.2\n");
        printf("Type the following line:\n\n");
        printf("%s\n",s);
    }
    
    void displayerrors(int x)
    {
        printf("\n\nERRORS:%i\n",x);
    }
    
    int again()
    {
        int x;
        printf("\n\nTry again? [y/n]\n");
        x = getch();
        
        if(x == 'y'|| x == 'Y')
            return 1;
        else
            return 0;
    }
    
    void clrscrn()
    {
        system("cls");
    }
    
    void pause()
    {
        system("pause");
    }
        
    void main()
    {
        char string[19]= "";
        char *s;
        s = string;
        int error;    //numbers of errors while typing
        int tryagain;
        
        seedrand();
        
        do
        {    
            fillstring(s); 
            clrscrn();       
            startmsg(s);
            error = getinput(s);
            displayerrors(error);
            tryagain = again();
        }
        while(tryagain);
    }

  4. #19
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    I typically prototype all my functions at the beggining of a file so I don't have to worry about their order. I'm nut sure if there's any reason to do this 100% of the time, but it usually comes in handy as your program's size increases.

  5. #20
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Quote Originally Posted by sand_man
    Code:
    void fillstring(char *s,char *keys,int size);
    void typestring(char *s);
    prototypes dont need names
    Code:
    void fillstring(char *,char *,int);
    void typestring(char *);
    o_O

    including names on the prototypes lets you make some sense of them

    Code:
    void myfunc3 (int, int, int, void *, const char *, char **, unsigned short);
    know what that does? neither do i.
    hello, internet!

  6. #21
    Registered User
    Join Date
    Nov 2003
    Posts
    28
    if you don not include names in the prototypes then how do I use them in the function?

    for example if i do this

    Code:
    void function1(int);   //prototype without name
    
    main()
    {
        int x;
        x=10;
       
        function1(x);
    
        return 0;
    }
    
    void function1(int)
    {
    
        //if there is not name with int then how do i use the variable that was passed to it?
    }

  7. #22
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Because prototyping just tells the compiler that a function with that name and those parameter types exists somewhere and its valid to call it. When you define the function you have to give the parameters names.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with a program, theres something in it for you
    By engstudent363 in forum C Programming
    Replies: 1
    Last Post: 02-29-2008, 01:41 PM
  2. Replies: 4
    Last Post: 02-21-2008, 10:39 AM
  3. Using variables in system()
    By Afro in forum C Programming
    Replies: 8
    Last Post: 07-03-2007, 12:27 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM