Thread: large program code ,please help

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    119

    large program code ,please help

    Hi, sorry that this is such a large program, but I was putting together what I learned, and so I made a function that would read in a number from the user, and perform some input validation, then return whatever number to the function that called it. Here is the *crazy* part - the number must be between 0 and 9999, and if the user enters a larger number, or just hits enter, or enters letters, or enters "123abc" -- any of that, it works like it should, and reprompts them for the info. What's ticking me off is that the program works fine if they enter the right thing the first time, but if they don't when it reprompts them for the information, even if they enter a valid value, it doesn't work! It skips returning to the function that called it like it should (unless they enter a valid value the first time), and even skips to different lines in the program for no reason. I'm using the latest version of dev-c++ and win xp. It's the function getname where this happens. I've put some printf's in there for debugging purposes. If anyone can help, that would be greatly appreciated, because I've spent hours looking over this and I believe I'm not doing anything wrong, but it's making me question my desire to continue to program in c if it's this buggy, I mean, I can handle bugs, but how in the hell can you write a good program if even when you do everything right, it f**** up? Please tell me I'm just doing something wrong here, and somehow missing it, because I love what C I do know...

    Here's the code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    void color(int colour) {
         HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
         if (colour == 1) {
            SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
            return;
            }
    
        if (colour == 2) {
            SetConsoleTextAttribute(hOut, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
            return;
            }
    
        if (colour == 3) {
           SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
           return;
           }
    }                                    //close: color()
    
    void cls() {
    
         HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
         COORD position;
         DWORD written;
    
         position.X = 0;
         position.Y = 0;
    
         FillConsoleOutputCharacter(hOut, ' ', 6000, position, &written);
    
         // The code below makes sure after clearing the screen you start out again at 0,0
    
         SetConsoleCursorPosition(hOut,position);
    
         return;
    
    }                                     //close: cls()
    
    void cb() {
         int cb;
    
         while ((cb = getchar()) != '\n');
    
         return;
    
    }                                     //close: cb()
    
    
    //figure out a way to put the stuff above in a header & lib file
    
    
    void getname(char *name);
    int getnum(int max);
    
    
    
    int lp;
    int nchars;
    int rc;
    
    
    void story();
    void mm();
    void about();
    
    
    
    
    int main()
    {
      SetConsoleTitle("Smith Sayings - Freeware Edition");
      mm();
      return 0;
    }
    
    void mm() {
    int nchars;
    int input;
    char ui[256];  //ui = User Input
    int rc;      //rc = Return Code
    char spaces[] = "\n\n\n\n\n\n\n\n";
    char overflow = 'T';   //assign it to something, don't chance leaving it blank...
    
         cls();
         color(2);
         printf(spaces);
         printf("\t\tWelcome to Smith Sayings - Freeware Edition\n\n");
         color(1);
         printf("\t\t            Choose an option:\n\n");
         color(3);
         printf("\t\t               1.Run Story\n\n");
         printf("\t\t               2.About\n\n");
         printf("\t\t               3.Exit\n\n");
         color(1);
         printf("\n\t\t               Choice: ");
         color(3);
    
                fgets(ui,sizeof(ui),stdin);
    
                for (lp = 0; lp < sizeof(ui); lp++) {
    
                                  if (ui[lp] == '\n') {
                                             overflow = 'F';
                                             ui[lp] = '\0';
                                                      }
    
                }  //endof: for (loop)
    
               if (overflow != 'F') {
                  cb();
                  }
    
       rc = sscanf(ui,"%d%n",&input,&nchars); //parse thru the string, get a returncode, to see how many values
                                                      //it succesfully read in   (should be 1 int in this case)
               if (rc == 1) {
    
                  if (ui[nchars] == '\0') {
                                 if (input == 1) { story(); }
                                 if (input == 2) { about(); }
                                 if (input == 3) { exit(0); }
    
                                 else mm();
                                 }    //close - if they typed 1 value that was read in, followed by ENTER
                                       // i.e. 6 <ENTER>, or 1 <ENTER> or 1532<ENTER>
    
                                mm();  //if rc==1 but they typed more than 1 thing before ENTER
                                     } //i.e. 1md83js then hit ENTER
    
    mm();         //if rc != 1 (so sscanf wasn't able to read in any integer, i.e. they typed "m", or "mfjefeijfe"
    
         } //close of mainmenu (mm)
    
    
    void story() {
    
         char name1[17];
         int num1;
         int num2;
         char adj1[50];
         char adj2[50];
         char adj3[50];
         char adj4[50];
         char adj5[50];
         char noun1[50];
         char noun2[50];
         char noun3[50];
         char verb_ing1[50];
         char verb_ing2[50];
         char verb_ing3[50];
         char verb1[50];
         char noun_s1[50];
    
    cls();
    color(1);
    printf("Enter in the numbers and words the program asks you for below, the brackets ([])have a number inside them");
    printf(" showing you the maximum amount of characters you can\ntype in for that number. It's the same for words, and spaces count as well.\n");
    printf("When entering a number, no commas are allowed.\n\n");
         color(3);
    
         getname(name1);
    
         num1 = getnum(0);   //getnum(max size) if 0, max size is 9999
    
    
    
    
    
         printf("Adjective:");
         fgets(adj2, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                           if (adj2[lp] == '\n') {
                                        adj2[lp] = '\0';
                                        break; }
                                        }
         printf("\nNoun:");
         fgets(noun2, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                           if (noun2[lp] == '\n') {
                                        noun2[lp] = '\0';
                                        break;}
                                          }
         num2 = getnum(12);
    
     //    printf("\nNumber:");  //max 12
    //     fgets(num2,10,stdin);
     //    for (lp = 0; lp < 10; lp++) {
      //                     if (num2[lp] == '\n') {
      //                                num2[lp] = '\0';
         //                             break; }
       //                               }
         printf("\nAdjective:");
         fgets(adj3, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                           if (adj3[lp] == '\n') {
                                        adj3[lp] = '\0';
                                        break; }
                                        }
    
    
         printf("\nVerb ending in -ing:");
         fgets(verb_ing2, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                         if (verb_ing2[lp] == '\n') {
                                        verb_ing2[lp] = '\0';
                                        break; }
                                        }
    
         printf("\nAdjective:");
         fgets(adj5, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                           if (adj5[lp] == '\n') {
                                        adj5[lp] = '\0';
                                        break; }
                                        }
    
         printf("\nNoun:");
         fgets(noun1, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                           if (noun1[lp] == '\n') {
                                        noun1[lp] = '\0';
                                        break; }
                                        }
    
         printf("\nAdjective:");
         fgets(adj1, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                           if (adj1[lp] == '\n') {
                                        adj1[lp] = '\0';
                                        break; }
                                        }
    
    
         printf("\nNoun:");
         fgets(noun3, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                           if (noun3[lp] == '\n') {
                                        noun3[lp] = '\0';
                                        break; }
                                        }
    
    
         printf("\nVerb ending in -ing:");
         fgets(verb_ing1, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                         if (verb_ing1[lp] == '\n') {
                                        verb_ing1[lp] = '\0';
                                        break; }
                                        }
    
         printf("\nAdjective:");
         fgets(adj4, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                           if (adj4[lp] == '\n') {
                                        adj4[lp] = '\0';
                                        break; }
                                        }
    
    
         printf("\nVerb ending in -ing:");
         fgets(verb_ing3, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                         if (verb_ing3[lp] == '\n') {
                                        verb_ing3[lp] = '\0';
                                        break; }
                                        }
    
         printf("\nVerb:");
         fgets(verb1, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                         if (verb1[lp] == '\n') {
                                        verb1[lp] = '\0';
                                        break; }
                                        }
    
         printf("\nNoun (plural):");
         fgets(noun_s1, 25, stdin);
         for (lp = 0; lp < 25; lp++) {
                         if (noun_s1[lp] == '\n') {
                                        noun_s1[lp] = '\0';
                                        break; }
                                        }
    
         cls();
    
         printf("The Legend of Bigfoot\n\n");
         printf("Bigfoot was an urban legend of deacades ago. This creature was rumoured to have\n");
         printf("stood");
         color(1);
         printf(" %d",num1);
         color(3);
         printf(" ft,");
         color(1);
         printf("%d",num2);
         color(3);
         printf(" in. tall, and was very %s.The scientific name given\n",adj1);
         printf("to Bigfoot was Sasquatch.\n");
         printf("There are many tales of him %s people who were camped out to find him.\nThey would set up", verb_ing1);
         printf(" a trap to try and catch him, and put a %s in the\ntrap for him to try and %s.\n\n",noun1, verb1);
    
         printf("Many of the %s locals were very scared of Bigfoot.\nOften, it was said, you could hear", adj2);
         printf(" his %s scream late in the night.\nTrackers have often stumbled upon %s said to be that", adj3,noun_s1);
         printf(" of the Sasquatch.\nOne villager named %s said he had an up close encounter\nwith the", name1);
         printf(" %s %s.\n\n", adj4, noun2);
    
         printf("He said he was out in the woods one day, %s his %s,\nwhen out of nowhere he witnessed",verb_ing2,noun3);
         printf(" Bigfoot %s by in the woods.\nHe said he would have taken a picture, but he was afraid",verb_ing3);
         printf(" of getting the \n%s monster's attention.\n\n",adj5);
    
         printf("To this day, the legend of Bigfoot remains unsolved.\n");
    
         printf("\nPress <ENTER> to return to the main menu\n");
         getchar();
         mm();
         }
    
    void about() {
    
    cls();
    printf("\n\n\n\n\n");
    color(3);
    printf("This version of Smith Sayings is"); color(2); printf(" freeware");color(3); printf(", meaning you are free to make copies\n");
    printf("and distribute it as you see fit, provided that the files that accompanied it\n");
    printf("are distributed with it as well.\n");
    printf("\nIf you like this version, you may be interested in getting the full version,\n");
    printf("which comes with 20 stories, or the deluxe version, which has all the stories\n");
    printf("that the full version has, plus 10 more, and a random word generator.\n");
    printf("The full version retails for $15 dollars, and the deluxe retails for $25.\n");
    printf("Thanks for trying out this program, I hope you had as much fun using it\n");
    printf("as I did making it!\n");
    color(1);
    printf("\n-Ash\n");
    color(3);
    printf("\nPress <ENTER> to return to the main menu\n");
    getchar();
    mm();
    }
    
    
    void getname(char *name) {
    
                      int overflow = 1; //if you just did "int overflow" it might end up setting it to 0.
                      int input;
    
                      color(3);
                      printf("Name [15]: ");
    
                      color(2);
                      fgets(name,17,stdin); //0 - 14 = 15 char's. save 1 for the \n(15), and 1 for the \0(16).
                      //and since fgets reads in 1 less than what you tell it, make it 17.
                      //it reads in 1 less, and makes "x - 1" = \0. So in this case where the # is 17, it reads in 16,
                      //and makes name[16] = \0.
    
                      //check if they overloaded the buffer, replace \n with \0, see if just hit enter, or num's
    
                      //lp is global, as is rc and nchars
    
                      for (lp = 0; name[lp] != '\0'; lp++) {
    
                      if (name[lp] == '\n') {
                             overflow = 0;     //no overflow
                             name[lp] = '\0';
                             }
    
                             }  //end: for (loop)
    
                             rc = sscanf(name, "%d%n", &input, &nchars);
    
                    if (rc == 1) {
                       color(1);
                       printf("\nInvalid input, should be a name, try again.\n\n");
                       getname(name);
                       }
    
    
                    if ((rc == 1) && (overflow != 0)) {
                       color(1);
                       printf("\nInvalid input, should be a name, try again.\n\n");
                       cb();
                       getname(name);
                       }
    
                    if (overflow != 0) {
                       cb();
                       color(1);
                       printf("\nMaximum name size is 15 characters, please re-enter.\n\n");
                       getname(name);
                       }  //end: overflow check
    
                    if (name[0] == '\0') {
                       color(1);
                       printf("\nInvalid input, enter a name please.\n\n");
                       getname(name);
                       }
    
    return;
    }
    
    int getnum(int max) {
    
             //need to make it see if they sent 0 as their argument, in which case max size is 9999.
             //also check if they type in a negative number, if so tell them it must be positive.
             //tell them no commas allowed - check for this to.
    
             int max_size;
             char str[6];
    
             int input = 0;
             int overflow = 1;
    
             if (max == 0) max_size = 9999;
             else max_size = max;
    
             color(3);
             printf("Number [max size = %d]: ", max_size);
             color(2);
    
             fgets(str, sizeof(str), stdin);
    
             rc = (sscanf(str, "%d%n", &input, &nchars));
             printf("\ninput = %d\n", input);
             if (str[0] == '\n') {
                printf("\nstr[0] = \\n\n");
     //           cls();
                getnum(max);
                } //close: <if they just hit enter>
    
    
              printf("\nabout to enter loop:input = %d\n", input);
             for (lp = 0; str[lp] != '\0'; lp++) {
    
                printf("\nentered the loop: str[%d] = \'%c\'\n", lp, str[lp]);
    
                 if (str[lp] == '\n') {
                    overflow = 0;
                    str[lp] = '\0';
                    printf("\nfound \\n in string(str[%d]),changed to \\0, overflow set to 0\n",lp);
                    printf("\ninput = %d\n", input);
                    } //close: <replace \n with \0, see if they overflowed it>
                }  //close: for (loop)
    
    
    
    
             if (rc != 1) {
       printf("\nrc != 1\n");
     //           cls();
    
                if (overflow != 0) {
                   printf("\n [rc != 1], overflow != 0, clearing buffer\n");
                   cb();
                   }
    
                   getnum(max);
    
                } //close: <if they didn't enter a number>
    
    
    
            if (rc == 1) {
               printf("\n got a number\n");
                printf("\ninput = %d\n", input);
    
               if (overflow != 0) {
              printf("\n [got a number] overflow != 0, cb()\n");
               cb();
     //         cls();
               getnum(max);
               }
    
               printf("about to compare, input = %d", input);
               if (input > max_size) {  printf("\n input > max_size \n");
                  printf("\ninput = %d, max_size = %d\n", input, max_size);
    // cls();
                  getnum(max);
                  }   //close: <if number exceeds max size>
    
               if (str[nchars] != '\0') {
               printf("\nstr[nchars] = %d\n", nchars);
               printf("\n str[nchars] != '\\0'\n");
               printf("\n str[%d] = '\\0'", nchars);
    //     cls();
                  getnum(max);
                  } //close: <if they typed a number followed by letters>
    
                 } //close: <if they typed in a valid number>
            printf("\nreturning to func with input\n");
             printf("\ninput = %d\n", input);
    
             return input;
    
             }  //endof: getnum()

  2. #2
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    sorry for all the //'s -- they are there from where i was upgrading it, and of course the info under "about" in the program isn't quite true yet, I have no registered or deluxe version.

    Here's something I've noticed: I run it, and type in 25000 when it prompts : number [max 9999] - and what happens is it does what it should, and prompts me again, this time for a valid number. So this time I type 9500, then when I hit enter, because of all my debugging printf's, you can see that it sets the variable "input" to 9500 like it should, but right before it checks to see if "input < max_size" for some wacko reason it sets "input" back to 25000....WTF??

  3. #3
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    Oh yeah, and it says "returning to function" but then it doesn't execute the very next line, which is "return input;", it skips about 10 lines up in the code for no apparent reason!

    I'm starting to think that either DevC has a lot of bugs (at least running under winxp maybe?), or I'm nuts....

  4. #4
    Registered User
    Join Date
    Jan 2006
    Posts
    63
    Hi, I don't know the answer yet as I have only glanced over it but I can try and give you some advice so far.

    Consistency is an important part of writing code, it makes readability a lot easier. For example I notice you switch between using different types of braces and you also change the amount of spaces you indent your code.

    I would suggest trying to use the same style throughout the code.

    For the 3 functions at the top, you say in the comments you want to put them in a header, well copy them into a header file (.h) try to make the name quite descriptive.
    and then at the top of your code under the other headers put #include "headername.h"

    Or if you decide to leave those functions in the main file, then copy them to below main() and prototype them at the top like you do with the other functions.

    Just a little advice.

  5. #5
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    Ok well hey thanks for that, I'll definatly do that. I should know better, but I was so excited and in such a hurry to make this program, that I didn't remain consistant. I appreciate the help on the header thing, that should make things better. Also I used a visual debugger that comes with dev-c and the main thing seems to be that if the user enters a valid value when prompted for the very 1st time, all works well, and when it gets to "return input;", it returns to story() just like it should. However, if they enter a value that's not valid, when it prompts them again for a valid value, all is well until the line "return input" - it doesn't, it skips up 10 lines and uses whatever value they used the 1st time (the invalid one).

    Thanks again, I just really need to get this fixed or else I'm really stuck here

  6. #6
    Registered User
    Join Date
    Jan 2006
    Posts
    63
    Okay I think I found and fixed the error for you, I rewrote the code sorting out the indentation and braces. I also moved the functions from the top to the bottom and prototyped them at the top.

    You might notice that under every for() loop I have a single line gap, incase you are wondering why, well the reason is there is no reason inparticular. As I was sorting the braces and indentation, I put a gap on the first few for() loops because I thought it might make it easier to read for you with the spaces.

    Then I thought well maybe it wont, but by this time I had already done it to a few of the loops, so rather than go back and remove the space I just kept going and doing it to every for() loop. After all what kind of person would I be if I tell you about consistency and then I am not consistent with my code?

    Anyway in the end it seems to have come down to a missing return statement. The code should have returned at a certain point but instead would have continued to run through the program.

    Here is the code which I have changed.

    Code:
    // Header files
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    // Function prototypes
    void story();
    void mm();
    void about();
    void getname(char *name);
    int getnum(int max);
    void color(int colour);
    void cls();
    void cb();
    
    // Global variables
    int lp;
    int nchars;
    int rc;
    
    // Our program starts here 
    int main(){
    	
    	SetConsoleTitle("Smith Sayings - Freeware Edition");
    	mm();
    	
    	return 0;
    }
    
    void mm() {
    	
    	int nchars;
    	int input;
    	char ui[256];  //ui = User Input
    	int rc;      //rc = Return Code
    	char spaces[] = "\n\n\n\n\n\n\n\n";
    	char overflow = 'T';   //assign it to something, don't chance leaving it blank...
    	
    	cls();
    	color(2);
    	printf(spaces);
    	printf("\t\tWelcome to Smith Sayings - Freeware Edition\n\n");
    	color(1);
    	printf("\t\t            Choose an option:\n\n");
    	color(3);
    	printf("\t\t               1.Run Story\n\n");
    	printf("\t\t               2.About\n\n");
    	printf("\t\t               3.Exit\n\n");
    	color(1);
    	printf("\n\t\t               Choice: ");
    	color(3);
    	
    	fgets(ui,sizeof(ui),stdin);
    	
    	for (lp = 0; lp < sizeof(ui); lp++) {
    		
    		if (ui[lp] == '\n') {
    			overflow = 'F';
    			ui[lp] = '\0';
    		}
    	}  //endof: for (loop)
    	
    	if (overflow != 'F') {
    		cb();
    	}
    
    	//parse thru the string, get a returncode, to see how many values
    	rc = sscanf(ui,"%d%n",&input,&nchars);
    	//it succesfully read in   (should be 1 int in this case)
               
    	if (rc == 1) {
    		
    		if (ui[nchars] == '\0') {
    			
    			if (input == 1) { story(); }
    			if (input == 2) { about(); }
    			if (input == 3) { exit(0); }
    			
    			else mm();
    		}   //close - if they typed 1 value that was read in, followed by ENTER
    			// i.e. 6 <ENTER>, or 1 <ENTER> or 1532<ENTER>
    		
    		mm();  //if rc==1 but they typed more than 1 thing before ENTER
    	} //i.e. 1md83js then hit ENTER
    	
    	// if rc != 1 (so sscanf wasn't able to read in any integer, 
    	// i.e. they typed "m", or "mfjefeijfe"
    	mm();
    } //close of mainmenu (mm)
    
    void story() {
    	
    	char name1[17];
    	int num1;
    	int num2;
    	char adj1[50];
    	char adj2[50];
    	char adj3[50];
    	char adj4[50];
    	char adj5[50];
    	char noun1[50];
    	char noun2[50];
    	char noun3[50];
    	char verb_ing1[50];
    	char verb_ing2[50];
    	char verb_ing3[50];
    	char verb1[50];
    	char noun_s1[50];
    	
    	cls();
    	color(1);
    	printf("Enter in the numbers and words the program asks you for below, the brackets ([])have a number inside them");
    	printf(" showing you the maximum amount of characters you can\n");
    	printf("type in for that number. It's the same for words, and spaces count as well.\n");
    	printf("When entering a number, no commas are allowed.\n\n");
    	color(3);
    	
    	getname(name1);
    	
    	//getnum(max size) if 0, max size is 9999
    	num1 = getnum(0);
    	
    	printf("Adjective:");
    	fgets(adj2, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (adj2[lp] == '\n') {
    			adj2[lp] = '\0';
    			break;
    		}
    	}
    	
    	printf("\nNoun:");
    	fgets(noun2, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (noun2[lp] == '\n') {
    			noun2[lp] = '\0';
    			break;
    		}
    	}
    	
    	num2 = getnum(12);
    	
    	//  printf("\nNumber:");  //max 12
    	//  fgets(num2,10,stdin);
    	//  for (lp = 0; lp < 10; lp++) {
    	//        if (num2[lp] == '\n') {
    	//               num2[lp] = '\0';
    	//               break; }
    	//         }
    	
    	printf("\nAdjective:");
    	fgets(adj3, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (adj3[lp] == '\n') {
    			adj3[lp] = '\0';
    			break; 
    		}
    	}
    	
    	printf("\nVerb ending in -ing:");
    	fgets(verb_ing2, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (verb_ing2[lp] == '\n') {
    			verb_ing2[lp] = '\0';
    			break;
    		}
    	}
    	
    	printf("\nAdjective:");
    	fgets(adj5, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (adj5[lp] == '\n') {
    			adj5[lp] = '\0';
    			break;
    		}
    	}
    	
    	printf("\nNoun:");
    	fgets(noun1, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		if (noun1[lp] == '\n') {
    			noun1[lp] = '\0';
    			break; 
    		}
    	}
    	
    	printf("\nAdjective:");
    	fgets(adj1, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (adj1[lp] == '\n') {
    			adj1[lp] = '\0';
    			break; 
    		}
    	}
    	
    	printf("\nNoun:");
    	fgets(noun3, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (noun3[lp] == '\n') {
    			noun3[lp] = '\0';
    			break; 
    		}
    	}
    	
    	printf("\nVerb ending in -ing:");
    	fgets(verb_ing1, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		if (verb_ing1[lp] == '\n') {
    			verb_ing1[lp] = '\0';
    			break;
    		}
    	}
    	
    	printf("\nAdjective:");
    	fgets(adj4, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (adj4[lp] == '\n') {
    			adj4[lp] = '\0';
    			break;
    		}
    	}
    	
    	printf("\nVerb ending in -ing:");
    	fgets(verb_ing3, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (verb_ing3[lp] == '\n') {
    			verb_ing3[lp] = '\0';
    			break;
    		}
    	}
    	
    	printf("\nVerb:");
    	fgets(verb1, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (verb1[lp] == '\n') {
    			verb1[lp] = '\0';
    			break;
    		}
    	}
    	
    	printf("\nNoun (plural):");
    	fgets(noun_s1, 25, stdin);
    	for (lp = 0; lp < 25; lp++) {
    		
    		if (noun_s1[lp] == '\n') {
    			noun_s1[lp] = '\0';
    			break;
    		}
    	}
    	
    	
    	cls();
    	
    	printf("The Legend of Bigfoot\n\n");
    	printf("Bigfoot was an urban legend of deacades ago. This creature was rumoured to have\n");
    	printf("stood");
    	color(1);
    	printf(" %d",num1);
    	color(3);
    	printf(" ft,");
    	color(1);
    	printf("%d",num2);
    	color(3);
    	printf(" in. tall, and was very %s.The scientific name given\n",adj1);
    	printf("to Bigfoot was Sasquatch.\n");
    	printf("There are many tales of him %s people who were camped out to find him.\nThey would set up", verb_ing1);
    	printf(" a trap to try and catch him, and put a %s in the\ntrap for him to try and %s.\n\n",noun1, verb1);
    	
    	printf("Many of the %s locals were very scared of Bigfoot.\nOften, it was said, you could hear", adj2);
    	printf(" his %s scream late in the night.\nTrackers have often stumbled upon %s said to be that", adj3,noun_s1);
    	printf(" of the Sasquatch.\nOne villager named %s said he had an up close encounter\nwith the", name1);
    	printf(" %s %s.\n\n", adj4, noun2);
    	
    	printf("He said he was out in the woods one day, %s his %s,\nwhen out of nowhere he witnessed",verb_ing2,noun3);
    	printf(" Bigfoot %s by in the woods.\nHe said he would have taken a picture, but he was afraid",verb_ing3);
    	printf(" of getting the \n%s monster's attention.\n\n",adj5);
    	
    	printf("To this day, the legend of Bigfoot remains unsolved.\n");
    	
    	printf("\nPress <ENTER> to return to the main menu\n");
    	getchar();
    	mm();
    }
    
    void about() {
    	
    	cls();
    	printf("\n\n\n\n\n");
    	color(3);
    	printf("This version of Smith Sayings is");
    	color(2); 
    	printf(" freeware");
    	color(3);
    	printf(", meaning you are free to make copies\n");
    	printf("and distribute it as you see fit, provided that the files that accompanied it\n");
    	printf("are distributed with it as well.\n");
    	printf("\nIf you like this version, you may be interested in getting the full version,\n");
    	printf("which comes with 20 stories, or the deluxe version, which has all the stories\n");
    	printf("that the full version has, plus 10 more, and a random word generator.\n");
    	printf("The full version retails for $15 dollars, and the deluxe retails for $25.\n");
    	printf("Thanks for trying out this program, I hope you had as much fun using it\n");
    	printf("as I did making it!\n");
    	color(1);
    	printf("\n-Ash\n");
    	color(3);
    	printf("\nPress <ENTER> to return to the main menu\n");
    	getchar();
    	mm();
    }
    
    void getname(char *name) {
    	
    	int overflow = 1; //if you just did "int overflow" it might end up setting it to 0.
    	int input;
    	
    	color(3);
    	printf("Name [15]: ");
    	
    	color(2);
    	fgets(name,17,stdin); //0 - 14 = 15 char's. save 1 for the \n(15), and 1 for the \0(16).
    	                      //and since fgets reads in 1 less than what you tell it, make it 17.
    	                      //it reads in 1 less, and makes "x - 1" = \0. So in this case where the # is 17, it reads in 16,
    	                      //and makes name[16] = \0.
    	                      //check if they overloaded the buffer, replace \n with \0, see if just hit enter, or num's
    	                      //lp is global, as is rc and nchars
    	
    	for (lp = 0; name[lp] != '\0'; lp++) {
    		
    		if (name[lp] == '\n') {
    			overflow = 0;     //no overflow
    			name[lp] = '\0';
    		}
    	}  //end: for (loop)
    	
    	rc = sscanf(name, "%d%n", &input, &nchars);
    	
    	if (rc == 1) {
    		color(1);
    		printf("\nInvalid input, should be a name, try again.\n\n");
    		getname(name);
    	}
    	
    	if ((rc == 1) && (overflow != 0)) {
    		color(1);
    		printf("\nInvalid input, should be a name, try again.\n\n");
    		cb();
    		getname(name);
    	}
    	
    	if (overflow != 0) {
    		cb();
    		color(1);
    		printf("\nMaximum name size is 15 characters, please re-enter.\n\n");
    		getname(name);
    	}  //end: overflow check
    	
    	if (name[0] == '\0') {
    		color(1);
    		printf("\nInvalid input, enter a name please.\n\n");
    		getname(name);
    	}
    	
    	return;
    }
    
    int getnum(int max) {
    	
    	
    	//need to make it see if they sent 0 as their argument, in which case max size is 9999.
    	//also check if they type in a negative number, if so tell them it must be positive.
    	//tell them no commas allowed - check for this to.
    	
    	int max_size;
    	char str[6];
    	
    	int input = 0;
    	int overflow = 1;
    	
    	if (max == 0) max_size = 9999;
    	else max_size = max;
    	
    	color(3);
    	printf("Number [max size = %d]: ", max_size);
    	color(2);
    	
    	fgets(str, sizeof(str), stdin);
    	
    	rc = (sscanf(str, "%d%n", &input, &nchars));
    	printf("\ninput = %d\n", input);
    	if (str[0] == '\n') {
    		printf("\nstr[0] = \\n\n");
    		//        cls();
    		getnum(max);
    	} //close: <if they just hit enter>
    	
    	printf("\nabout to enter loop:input = %d\n", input);
    	for (lp = 0; str[lp] != '\0'; lp++) {
    		
    		printf("\nentered the loop: str[%d] = \'%c\'\n", lp, str[lp]);
    		
    		if (str[lp] == '\n') {
    			overflow = 0;
    			str[lp] = '\0';
    			printf("\nfound \\n in string(str[%d]),changed to \\0, overflow set to 0\n",lp);
    			printf("\ninput = %d\n", input);
    		} //close: <replace \n with \0, see if they overflowed it>
    	}  //close: for (loop)
    
    	if (rc != 1) {
    		printf("\nrc != 1\n");
    		//      cls();
    		
    		if (overflow != 0) {
    			printf("\n [rc != 1], overflow != 0, clearing buffer\n");
    			cb();
    		}
    		
    		getnum(max);
    	
    	} //close: <if they didn't enter a number>
    	
    	if (rc == 1) {
    		printf("\ngot a number\n");
    		printf("\ninput = %d\n", input);
    		
    		if (overflow != 0) {
    			printf("\n[got a number] overflow != 0, cb()\n");
    			cb();
    			// cls();
    			return getnum(max);
    		}
    		
    		printf("about to compare, input = %d", input);
    		if (input > max_size) {
    			printf("\n input > max_size \n");
    			printf("\ninput = %d, max_size = %d\n", input, max_size);
    			// cls();
    			getnum(max);
    		}   //close: <if number exceeds max size>
    
    		if (str[nchars] != '\0') {
    			printf("\nstr[nchars] = %d\n", nchars);
    			printf("\n str[nchars] != '\\0'\n");
    			printf("\n str[%d] = '\\0'", nchars);
    			// cls();
    			getnum(max);
    		} //close: <if they typed a number followed by letters>
    
    	} //close: <if they typed in a valid number>
    	
    	printf("\nreturning to func with input\n");
    	printf("\ninput = %d\n", input);
    	
    	return input;
    
    }  //endof: getnum()
    
    void color(int colour) {
    	
    	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    	if (colour == 1) {
    		SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
    		return;
    	}
    	
    	if (colour == 2) {
    		SetConsoleTextAttribute(hOut, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
    		return;
    	}
    	
    	if (colour == 3) {
    		SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    		return;
    	}
    }                                    //close: color()
    
    void cls() {
    	
    	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    	COORD position;
    	DWORD written;
    	
    	position.X = 0;
    	position.Y = 0;
    	
    	FillConsoleOutputCharacter(hOut, ' ', 6000, position, &written);
    	
    	// The code below makes sure after clearing the screen you start out again at 0,0
    	
    	SetConsoleCursorPosition(hOut,position);
    	
    	return;
    }                                     //close: cls()
    
    void cb() {
    	
    	int cb;
    	
    	while ((cb = getchar()) != '\n');
    	
    	return;
    }                                     //close: cb()
    With the code as it is, the line which needed changing is line 440.

    Or this here
    Code:
    			return getnum(max);
    Also another piece of advice which you might find useful, don't make your printf()'s and comment lines to long, go down to the next line instead.
    Some people prefer comments to be above the code rather than next to it aswell, but this is personal preference.

  7. #7
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    Great thanks sooo much, it works now! But I'm just curious, why is it that you just changed that one line to "return getnum(max)", but left the others still just as "getnum(max)"? I was wondering if there was a particular reason I should know why you just changed that one.

  8. #8
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    Also I had been making a smaller program to illustrate the same problem as in the code above, and I made the changes to it, and if you look at it, you'll see it's still functioning weird, if I could ask you this one more favor, please tell me what's going on in this much smaller program. What happens is it asks for a value up to 9999. And just like the program above, if you enter a num < 9999 the 1st time it prompts you, it works fine and prints "you entered 9999" (or whatever # you entered). The problem is that if you enter 10000 the 1st time it prompts you, it says "too large" like it should, but then when it prompts you the second time, if you enter 9999 it says "you entered 10000", even tho that was the value
    from when it first prompted you not the second time.....any idea as to why?

    Code:
    #include <stdio.h>
    int maxsize = 0;
    int getnum(int max);
    
    
    
    int main() {
        
        
        int num1;
        
        num1 = getnum(maxsize);
        
        printf("you entered %d", num1);
        
        getchar();
        
        
        
    
    
    
    return 0;
    }
    
    int getnum(int max) {
        int input;
        int nchars;
        int lp;
        char str[6];
        int max_size;
        int overflow = 1;
        int rc;
        int cb;
        if (max == 0) {
                max_size = 9999;
                }
        else max_size = max;
        
        printf("Enter a number (max 9999):");
        fgets(str, sizeof(str), stdin);
        for (lp = 0; str[lp] != '\0'; lp++) {
                if (str[lp] == '\n') {
                            str[lp] = '\0';
                            overflow = 0; //for false
                            }
                            }
        
        if (str[0] == '\0') {
                  return getnum(max);
                   }
        
        rc = sscanf(str, "%d%n", &input, &nchars);
        
        if (rc != 1) {
               
               if (overflow != 0) {
                            while ((cb=getchar()) != '\n');
                            }
               
               printf("you didn't enter a number");
               
               return getnum(max);
               }
               
        if (str[nchars] != '\0') {
                        
                        if (overflow != 0) {
                                     while ((cb=getchar()) != '\n');
                                     }
                       printf("you typed letters in with the numbers");
                       return getnum(max);
                        }
                        
        if (input > max_size) {
                  
                  printf("too large");
                  getnum(max);
                  }
                        
        return input;
                        
        
                   
        
        getchar();
        
    }

  9. #9
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    LOL, nevermind, I had missed a line which I went back to and changed to "return getnum", now it's working much better, sorry about that!

  10. #10
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    And actually I think I just awnsered my other question as well, I changed them all to return getnum and now things are working awesome, I'm gonna hook you and salem and cvr and some other helpful people around here up with my program once it's done (the full version to ) because without your guy's help, I could never have done it...

    So I guess just 1 question is all I really need awnsered now: When you are calling a function from inside itself, you should use "return" before the func name huh?

    I believe it was Salem who said that calling main() recursivley (which I think means from inside itself) is bad, but I was wondering if anyone knew why, and if that only applied to main()? (I should hope so, because if I couldn't call any function from inside itself, it seems like making some programs would be really hard)

  11. #11
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    Recursion - The act of a function calling itself. This is totally legal
    and is an alternative to using iteration to repeat code. However
    you should always introduce some form of condition that stops
    the code from repeating "infinitely" (this doesnt happen, even
    though you would expect it to). Recursion has a wide number of
    applications, and is considered an eloquent alternative to plain old
    iteration. Take a look at this code:

    Code:
    #include <stdio.h>
    
    void recursive_function (int call_num)
    {
    	printf ("Call - %d\n", call_num);
    	call_num++;
    	recursive_function (call_num);
    }
    
    
    int main ()
    {
    	recursive_function (0);
    	return 0;
    }
    This is a very simple example of bad recursion, it looks like it will
    loop infinitely, but it doesnt. Recursive calls are stored on a
    structure called a stack - once too many are loaded, the stack
    "unwinds", thus preventing infinite loops. Here is the same code
    again, but with an added check (base case is the term):

    Code:
    #include <stdio.h>
    
    void recursive_function (int call_num)
    {
    	if (call_num == 10)
    		return;
    	printf ("Call - %d\n", call_num);
    	call_num++;
    	recursive_function (call_num);
    }
    
    
    int main ()
    {
    	recursive_function (0);
    	return 0;
    }
    as Salem said, its probably not a good idea to recursively call your
    entire program - it just seems a bit dodgy. You would definitely
    have to have some very good reason to do it and some very
    sound base case. It can however, be used effectively with other
    functions. I guess the reason is that if main enters what would
    appear to be an infinite recursive loop, your program shuts down
    but if other functions do it, they eventually return to main - safer.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  12. #12
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    thanks for the info, it's greatly appreciated. But I noticed that in my program above, it has crazy bugs if i just do "getnum(max)", but if I do "return getnum(max)", it's fine. Do you usually do this as well? I'm just trying to see if I should do that in the future, because in this case it made my program work fine like it should.

  13. #13
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    i didnt look through the modified code, but since you were talking about recursion in the
    last posts, i'll assume that is what you're talking about. I haven't encountered that before
    but then again i dont use recursion all that much. it shouldnt be a problem the first way
    if you have good base cases, and it may be that adding return is producing a base case of
    some form. i am only hazzarding guesses at this point, but i'd say to stick with whatever
    works well for this code, and the next time you use recursion, be sure to add base cases
    carefully. I hope that helped at least in some way...
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  14. #14
    Registered User
    Join Date
    Jan 2006
    Posts
    63
    recursion has already been explained by the people above me so I have no need but I'll explain why you need the return statement.

    The first time the getnum() function is called is by here
    Code:
    	getname(name1);
    	
    	//getnum(max size) if 0, max size is 9999
    	num1 = getnum(0);
    So now we step into the getnum() function, going through the code.

    If everything goes well the first time it will execute this line of code

    Code:
    return input;
    So num1 will equal input.

    ----------------------------
    Now then, here is what happens if we input the incorrect answer.

    Code:
    		if (overflow != 0) {
    			printf("\n[got a number] overflow != 0, cb()\n");
    			cb();
    			// cls();
    			getnum(max);
    		}
    It will call getnum() again for you to put in a correct number, if you put in an incorrect number again the getnum() will be called again from inside itself, and it will continue to do this until you put in a correct number.

    but as soon as you put in a correct number, it comes from this line
    Code:
    getnum(max);
    and goes down to the next piece of code.

    Code:
    		if (input > max_size) {
    			printf("\n input > max_size \n");
    			printf("\ninput = %d, max_size = %d\n", input, max_size);
    			// cls();
    			getnum(max);
    		}   //close: <if number exceeds max size>
    So you will notice even though you input the correct number, it called getnum() again and that is why it didn't work properly. After executing the above piece of code. It would then execute the next piece of code.

    Code:
    		if (str[nchars] != '\0') {
    			printf("\nstr[nchars] = %d\n", nchars);
    			printf("\n str[nchars] != '\\0'\n");
    			printf("\n str[%d] = '\\0'", nchars);
    			// cls();
    			getnum(max);
    		} //close: <if they typed a number followed by letters
    So you can see after entering the correct number getnum() was called an extra 2 times when it wasn't needed. But by putting a return statement, it will return from the function after it executes the getnum() function. Stopping it from continuing though the code.

    You see you don't have to worry about it returning to early neither because it will only ever finish executing that getnum() when a correct number is put in, otherwise it keeps calling itself recursively.

    The reason I didn't change the other getnum()'s to return getnum() is because I never got to execute that code and notice the problem because the only test I was doing was entering 99999

    Also this code here

    Code:
    		printf("\nrc != 1\n");
    		//      cls();
    		
    		if (overflow != 0) {
    			printf("\n [rc != 1], overflow != 0, clearing buffer\n");
    			cb();
    		}
    		
    		getnum(max);
    	
    	} //close: <if they didn't enter a number>
    You should put a return for that aswell, but if you didn't I don't think it would matter too much unless the value of rc changed and it somehow entered the if(rc == 1) code block.

    Hopefully that explained everyhting for you.

  15. #15
    Registered User
    Join Date
    Dec 2005
    Posts
    119
    Thanks that was incredibly helpful, and I think I see what you mean, thanks for taking the time to look thru that mess, I'm definatly gonna code it more consistantly now

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Analyze code in large systems
    By Chrys in forum C Programming
    Replies: 5
    Last Post: 11-18-2008, 01:14 PM
  2. grade program code
    By jd7joe in forum C++ Programming
    Replies: 8
    Last Post: 11-18-2005, 04:48 PM
  3. prime number program code
    By jd7joe in forum C++ Programming
    Replies: 1
    Last Post: 11-17-2005, 10:14 AM
  4. Writing code for a program in C
    By Sure in forum C Programming
    Replies: 7
    Last Post: 06-11-2005, 01:33 PM
  5. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM