Unknown error with Y/N type system.

This is a discussion on Unknown error with Y/N type system. within the C Programming forums, part of the General Programming Boards category; For school (voluntary, not a required project), I'm creating a bonuscalc for the teachers to use. Everything is coming along ...

  1. #1
    Registered User
    Join Date
    Feb 2013
    Posts
    9

    Unhappy Unknown error with Y/N type system.

    For school (voluntary, not a required project), I'm creating a bonuscalc for the teachers to use. Everything is coming along smoothly, except for a portion of code that handles whether or not a file is present.

    The function is called 'isFoundDb' and is of type 'int'. It returns a value to main depending on whether or not the file is found, and whether or not the user chooses to use the default values in the absence of that file. If the file is found, return 1. If not found, AND the user chooses not to use the file (which is a sort of database), return 0. If the user wants to use the file, return -1.

    The program is split up into one file per function. 'Main.c' includes 'isFoundDb.c' and the .h file holding all the functions I have prototyped. Therefore, each .c file defines the functions in the .h file.


    isFoundDb.c:
    Code:
    #include <stdio.h>
    #include <conio.h>
    #include "bonusCalc.h"
    
    int isFoundDb() {
    
    char choice = -1;
    int cdn = -2;
    int i = 0;
    
    FILE *database;
    database = fopen("DATABASE.TXT","r");
    
    if (database == NULL) {
     printf("WARNING: \n");
     printf("Database file not found!\n");
     printf("Did you copy over the BIN folder?\n");
     printf("Default bonuses will be used.\n");
    
    do {
       printf("Is that okay? (y/n): ");
       fflush(stdin);
       choice = getch();
    
       switch(tolower(choice)) {
       case 'y': 
       cdn = 0;
       break;
       case 'n': 
       cdn = -1;
       break;
       default: printf("That isn't a valid choice\n");
       }
    
       if (cdn >= 0) {
       i = 1;
       }
       else {
       i = 0;
       }
       } while (i = 0);
    }
    
    else if (database != NULL) {
     cdn = 1;
    }
    else {
     cdn = -2;
     }
     
    return cdn;
    }
    Main.c:
    Code:
    #include <stdio.h>
    #include "bonusCalc.h"
    #include "isFoundDb.c"
    int main(int argc, char *argv[]) {
    int done = 0; /* Ensure that the following process isn't complete */
    int quit = 0; /* Should the program quit? */
    /* Check to make sure database.txt is present in the Bin folder
    * If isFoundDb returns 0, don't use db
    * If isFoundDb returns 1, use db
    * If isFoundDb returns -1, the file is missing and the user must locate the file */
    do {
    if (isFoundDb() == 0) {
     printf("\nUsing default values!\n");
     done = 1;
     }
    else if (isFoundDb() == 1) {
     printf("\nUsing database values!\n");
     done = 1;
     }
    else if (isFoundDb() == -1) {
     printf("\nDatabase.txt missing!\n");
     quit = 1;
     done = 1;
     }
    else {
     printf("Unknown error!\n");
     }
    } while (done != 1);
    return 0;
    }
    BonusCalc.h:
    Code:
    #ifndef bonusCalc_h
    #define bonusCalc_h
    int isFoundDb();
    #endif
    The code works perfectly except for when the user types 'n' in which case it repeats from the if (database == NULL) portion of code... which I don't understand. I'd have thought it would repeat from the embedded do while loop for some obscure reason. But what is perplexing is that if the user types 'y' it works fine. I'm at a loss.

    Any help would be appreciated

    PS: I tried using goto and even removing the do while loop but nothing's working.
    Last edited by JoshLalonde; 02-13-2013 at 07:19 AM.

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,681
    First indent your code.

    Second, never use goto, since it produces spaghetti code, which is not readable, thus can not be maintained.

    Third, welcome to the forum

    Last, but not least,
    Code:
    while (i = 0);
    You have forgotten an equal sign in line 34.
    Last edited by std10093; 02-13-2013 at 07:18 AM.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  3. #3
    Registered User
    Join Date
    Feb 2013
    Posts
    9
    Couldn't indent it since tab doesn't work, but I tried making it more blocky to help.
    Thanks
    And regarding goto, meh. It has its benefits, depends. Like, a quick way to exit a program in the case of an error... so just stick it in front of code you want to run if all your error checks fail. But, that's my opinion. I'm a noob, too, so :P

  4. #4
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,681
    Well, goto is considered to be by most of us not good. I could explain, but I am sure you will find enough info in google

    I think you didn't see my edited post
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  5. #5
    Registered User
    Join Date
    Feb 2013
    Posts
    9
    Oh, wow! Thanks.
    I tried compiling it with the i=0 corrected to i==0, but then it still doesn't work. Thanks though.

  6. #6
    Registered User
    Join Date
    Nov 2012
    Posts
    1,098
    Quote Originally Posted by JoshLalonde View Post
    And regarding goto, meh. It has its benefits, depends. Like, a quick way to exit a program in the case of an error...
    If you just want to exit in the case of an error, you should use exit(). As a slightly more flexible alternative, define a function called "fatal" that each of your functions will call if a fatal error happens. This function should just print an error message and then exit. This has the advantage that you can extend the function to do other things as your needs increase, like print a stacktrace when it is in debugging mode, for example.

    Another comment on your code - you are using fflush(stdin) which is probably causing a problem. What are you trying to do with that call?

  7. #7
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,681
    Ok, let's see the main now.

    How many times will your function isFoundDB will be executed?
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  8. #8
    Registered User
    Join Date
    Feb 2013
    Posts
    9
    I heard you're supposed to flush the buffer before running getch();. Also, the main.c is below the isFoundDb.c. I run and if-else sort of thing to see what the return value of isFoundDb() is. I think it'd be easier if I just send you the entire project so you can see what happens for yourself. If you'll do that for me, I'll give you a link.

  9. #9
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,703
    I heard you're supposed to flush the buffer before running getch();
    An odd suggestion, since getch by definition is unbuffered. The only way to prevent getch() from grabbing something is to avoid typing.

  10. #10
    Registered User
    Join Date
    Nov 2012
    Posts
    1,098
    Quote Originally Posted by JoshLalonde View Post
    I heard you're supposed to flush the buffer before running getch();
    No. Using fflush does not work on input streams. If you want to read one line of input, normally we use fgets. Also, if you indent your code you will notice another problem: at the top you do

    Code:
    if (database == NULL) {
    ...
    } else if (database != NULL) {
    ...
    } else {
    ...
    }
    The last part does not do anything because database can only be NULL or not NULL, there is no third possibility. One more thing. You are using cdn as your return value for this function. That means you can just return this value immediately once you set it. In other words, don't say cdn = 1. Just return 1.

    Your loop is really going to last forever until you return a valid value 0 or -1. So, in this case we write either while(1) ... or for ( ; ; )

    Finally you need to close the file if you opened it successfully.

    The modified function is below

    Code:
    int isFoundDb(void) {
     
    	char choice = -1;
    	 
    	FILE *database;
    	database = fopen("DATABASE.TXT","r");
    	 
    	if (database == NULL) {
    		printf("WARNING: \n");
    		printf("Database file not found!\n");
    		printf("Did you copy over the BIN folder?\n");
    		printf("Default bonuses will be used.\n");
    
    		while (1) {
    			printf("Is that okay? (y/n): ");
    			char buf[1000];
    			fgets(buf, sizeof(buf), stdin);
    			choice = buf[0];
    
    			switch(tolower(choice)) {
    				case 'y': 
    				return 0;
    				break;
    				case 'n': 
    				return -1;
    				break;
    				default: printf("That isn't a valid choice\n");
    			}
    		}
    	}
    	fclose(database);
    	return 1;
    }

  11. #11
    Registered User
    Join Date
    Feb 2013
    Posts
    9
    Thank you so very much for your help I knew there was something wrong with the loop, but I couldn't quite figure that out. And oh, lol. Thanks again, guys! I haven't checked it yet, but I'm going to assume what you've given me will work. So leave this open until I edit my post, thanks

    EDIT: Still not working!
    Below is a screenshot of running it in cmd.exe.

    EDIT2: I just realized the code you gave me is missing the else { }. Technically I guess it's not necessary, but I'm going to try to incorporate it to see if that helps.

    EDIT3: Wait, so the reason I assigned a 'cdn' variable was because of this. If for some odd reason the code ends up at the end of the function and it doesn't return anything, that's a problem... This code assumes that all the if/else stuff works. Even then, adding an else{} portion didn't help. Still repeats for some reason... Mayhaps it could be the compiler? I already discovered that the conio.h file was erroneous and could not be usei

    Name:  scr.jpg
Views: 53
Size:  76.9 KB

    Here is the changes I made:
    Code:
    #include <stdio.h>
    #include "Bonuscalc.h"
    
    
    int isFoundDb() {
     
        char choice = -1;
        int cdn = -3;
         
        FILE *database;
        database = fopen("DATABASE.TXT","r");
         
        if (database == NULL) {
            printf("WARNING: \n");
            printf("Database file not found!\n");
            printf("Did you copy over the BIN folder?\n");
            printf("Default bonuses will be used.\n");
    
    
            while (1) {
                printf("Is that okay? (y/n): ");
                char buf[1000];
                fgets(buf, sizeof(buf), stdin);
                choice = buf[0];
    
    
                switch(tolower(choice)) {
                    case 'y': 
                    cdn = 0;
                    break;
                    case 'n': 
                    cdn = -1;
                    break;
                    default: printf("That isn't a valid choice\n");
                }
                break;
            }
            
        }
        else {
            fclose(database);
            cdn = 1;
        }
        return cdn;
    }
    I'm aware that this breaks the repeated loop in case they don't enter N/n or Y/y. But that's a quick fix. I'm more concerned on why it repeats the IF/ELSE statement over again.
    Last edited by JoshLalonde; 02-13-2013 at 03:38 PM.

  12. #12
    Registered User
    Join Date
    Feb 2013
    Posts
    9
    Sorry for the double post, but it's for emphasis. I determined that there's a problem with the if/else in isFoundDb. I created a test file removing the embedded loops and it repeats infinitely. The only thing preventing it last time was the loops jumping to the end of the function.

    EDIT: Problem was with main.c and using a do while loop that wasn't supposed to be there. But now that the embedded loops are gone, it still repeats 3 times. (Essentially I forced it to act as if the user typed n).

    GRRRR Tested with GCC and didn't work either.
    Last edited by JoshLalonde; 02-13-2013 at 04:03 PM.

  13. #13
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by JoshLalonde View Post
    But now that the embedded loops are gone, it still repeats 3 times. (Essentially I forced it to act as if the user typed n).
    If your main() still looks like this:
    Code:
    if (isFoundDb() == 0) {
     printf("\nUsing default values!\n");
     done = 1;
     }
    else if (isFoundDb() == 1) {
     printf("\nUsing database values!\n");
     done = 1;
     }
    else if (isFoundDb() == -1) {
     printf("\nDatabase.txt missing!\n");
     quit = 1;
     done = 1;
     }
    else {
     printf("Unknown error!\n");
     }
    than you should read again std10093's post.

    Bye, Andreas

  14. #14
    Registered User
    Join Date
    Feb 2013
    Posts
    9
    Oh, so that's what the problem is. I should store the return value of isFoundDb into a variable and then check the variable rather than running the function each time and determining its return. Right? Also, since there's no other condition on which isFoundDb will quit. Just have two ifs, and the last else will be 'not found'.

    EUREKA! That's what it was. Fix was to store return value into a variable.
    Thanks for teaching me this important lesson about how C works, all of you

    You can close this thread now
    Last edited by JoshLalonde; 02-14-2013 at 03:14 PM.

  15. #15
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,681
    Εύρηκα! you said and you are right Bravo.

    Don't worry about the status of the thread
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. unknown type name __m128 not enabled
    By a.mlw.walker in forum C Programming
    Replies: 7
    Last Post: 10-03-2012, 11:40 AM
  2. Getting the data type of an unknown variable
    By adarpodracir in forum C Programming
    Replies: 6
    Last Post: 04-07-2012, 07:17 PM
  3. unknown file type reading
    By xixonga in forum C Programming
    Replies: 20
    Last Post: 11-28-2010, 11:17 AM
  4. Error-size of te type is unknown
    By as_rule in forum C Programming
    Replies: 5
    Last Post: 08-29-2010, 08:28 AM
  5. Replies: 11
    Last Post: 07-14-2010, 11:13 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21