Nube Programmer Needs Proofreader

Discussion in 'Mac Programming' started by stephanos180, Sep 9, 2008.

  1. macrumors member

    Joined:
    Aug 23, 2006
    Location:
    Downey, CA
    #1
    Hi, I've been working my way through "The C Programming Language" for about two days now, and am experimenting with some of the examples. Anyway, I'm at a point with what I call my 'Temperature Converter' where the app runs fine, except for the bolded part down below. You see, after I've entered '1' for Singly, and '1' or '2' for the next step, I input an integer, hit return, and have to do it once more to get a result. I don't understand why it's doing this. Please help, if you've got a moment; I can't figure it out.

    #include<stdio.h>

    int main()
    {
    int choice;

    printf("\n\nWelcome to the Temperature Converter\n");
    printf("\nWould you like to convert singly or incrementally?\n");
    printf("1. Singly\t2. Incrementally ");
    scanf("%d", &choice);

    if (choice == 1) {
    int choicetwo;

    printf("\nIn which direction would you like to convert?\n");
    printf("1. Celsius => Fahrenheit\t2. Fahrenheit => Celsius ");
    scanf("%d", &choicetwo);

    if (choicetwo == 1) {
    int fahrenheit, celsius;

    printf("\nPlease enter a starting value: ");
    scanf("%d\n", &celsius);
    fahrenheit = ((celsius * 9) / 5) + 32;
    printf("Your corresponding fahrenheit value: %d", fahrenheit);
    getchar();
    getchar();
    printf("\n");
    return 0;

    }

    else if (choicetwo == 2) {
    int fahrenheit, celsius;
    printf("\nPlease enter a starting value: ");
    scanf("%d\n", &fahrenheit);
    celsius = 5 * (fahrenheit - 32) / 9;
    printf("Your corresponding celsius value: %d", celsius);
    getchar();
    getchar();
    printf("\n");
    return 0;

    }

    }

    else if (choice == 2) {
    int fahrenheit, celsius;
    int lower, upper, step;

    printf("\nPlease enter a lower limit: ");
    scanf("%d", &lower);
    printf("Please enter an upper limit: ");
    scanf("%d", &upper);
    printf("Please enter a step size: ");
    scanf("%d", &step);

    while (fahrenheit <= upper) {
    celsius = 5 * (fahrenheit - 32) / 9;
    printf("%d\t%d\n", fahrenheit, celsius);
    fahrenheit = fahrenheit + step;
    }

    getchar();
    getchar();
    printf("\n");
    return 0;
    }

    }
     
  2. macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #2
    When you use scanf() as you are, the newline character is still sitting in the input buffer. You'll need to clear that newline character out of the input buffer. It would be more appropriate to clear it out just as soon as you issue the scanf() until some random time later on in the program.

    Here's some code I wrote not too long ago that show one technique for clearing out the buffer - there are several other techniques.

    (Just pay attention to the scanf() code - the other stuff might be more advanced code that you haven't experienced yet)

    Code:
    #include <stdio.h>
    
    #define STORE_NAME "Sierra Sporting Goods"
    
    void add_report() { 
    	printf("Report added\n") ; 
    	return ; 
    } 
    
    void report() { 
    	printf("Report run\n") ; 
    	return ; 
    } 
    
    void delete_record() { 
    	printf("record deleted\n") ; 
    	return ; 
    } 
    
    void change_record() { 
    	printf("record changed\n") ; 
    	return ; 
    } 
    
    int scanf_ok(int chars_read, int max, int * choice ) { 
    	if (chars_read == EOF || chars_read == 0 ) return 0 ; 
    	if (*choice < 1 || *choice > max) return 0 ; 
    	return 1 ; 
    } 
    
    
    int main(void) {
    	int response = 0;
    	int chars_read ; 
    	int i ; 
    	struct {
    		const char *text ;
    		void (*function)() ;
    	} item[] = {
    	
    		{ "Add a Report"   ,add_report		} , 
    		{ "Report"         ,report		} , 
    		{ "Delete a record",delete_record	} , 
    		{ "Change a record",change_record	} , 
    		{ "Quit"           ,0			}  
    	
    	} ;
    			
    	while ( 1 ) {
    
    		// Present the menu of options.  
    		printf("\t%s\n\n", STORE_NAME) ;
    		for (i = 0 ; i < ( sizeof(item) / sizeof(*item))  ; i++) { 
    			printf("%d = %s\n", i+1, item[i].text ) ; 
    		}
    
    		// Read the response and validate it and process it 
    		if ( scanf_ok( scanf("%d", &response), sizeof(item) / sizeof(*item) , &response ) ) {
    			if (item[response-1].function == 0) break ; 
    			else item[response-1].function() ; 
    		}
    		// else, tell user to try again.
    		else {
    			printf("Invalid or Non numeric value entered.  Try again.\n") ; 
    			while ( ( chars_read=getchar() ) != '\n' && chars_read != EOF) ;  /* clear buffer */ 
    		}
    
    	} // while 1  
    	return 0;
    }
     
  3. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #3
    Please use code tags. they look like this:
    [ CODE][ /CODE]
    without the spaces.

    Here's what I came up with:
    Code:
    #include<stdio.h>
    
    int main(int argc, char *argv[]) {
      int choice;
    
      printf("\n\nWelcome to the Temperature Converter\n");
      printf("\nWould you like to convert singly or incrementally?\n");
      printf("1. Singly\t2. Incrementally ");
      scanf("%d", &choice);
    
      if (choice == 1) {
        int choicetwo;
    
        printf("\nIn which direction would you like to convert?\n");
        printf("1. Celsius => Fahrenheit\t2. Fahrenheit => Celsius ");
        scanf("%d", &choicetwo);
    
        if (choicetwo == 1) {
          int fahrenheit, celsius;
    
          printf("\nPlease enter a starting value: ");
          scanf("%d", &celsius);
          fahrenheit = ((celsius * 9) / 5) + 32;
          printf("Your corresponding fahrenheit value: %d", fahrenheit);
          fflush(stdout);
          getchar();
          printf("\n");
        } else if (choicetwo == 2) {
          int fahrenheit, celsius;
          printf("\nPlease enter a starting value: ");
          scanf("%d", &fahrenheit);
          celsius = 5 * (fahrenheit - 32) / 9;
          printf("Your corresponding celsius value: %d", celsius);
          fflush(stdout);
          getchar();
          printf("\n");
        }
    
      } else if (choice == 2) {
        int fahrenheit, celsius;
        int lower, upper, step;
    
        printf("\nPlease enter a lower limit: ");
        scanf("%d", &lower);
        printf("Please enter an upper limit: ");
        scanf("%d", &upper);
        printf("Please enter a step size: ");
        scanf("%d", &step);
        fahrenheit=lower;
        while (fahrenheit <= upper) {
          celsius = 5 * (fahrenheit - 32) / 9;
          printf("%d\t%d\n", fahrenheit, celsius);
          fahrenheit = fahrenheit + step;
        }
    
        fflush(stdout);
        getchar();
        printf("\n");
      }
      return 0;
    }
    
    In your scanf you were looking for a signed integer, then a newline. If you just look for a signed integer, once you have entered one, plus a newline, scanf should return. toddburch also demonstrated a method to clear the buffer completely, but this may or may not be necessary at this point. I could have sworn originally you were also asking about the return type of main. Most compilers will default the return value of a function to int implicitly if you don't specify. int is the correct return type of main, and it's probably best to just declare it as such explicitly.

    -Lee
     
  4. macrumors member

    Joined:
    Jul 30, 2007
    Location:
    Trieste, Italy
    #4
    why you're using the getchar()? I dropped it out!
    try this (sorry, i don't have c compiler here, so this is no bullet proof code, but you can have some suggestion)
    bye
    DV

    Code:
    #include<stdio.h>
    	
    	int CelsToFahr(int celsius){
    		int result = ((celsius * 9) / 5) + 32;
    		// this result will be rounded!
    		return result;
    	}
       
    	int FahrToCels(int fahr){
    		int result = 5 * (fahr - 32) / 9;
    		// this result will be rounded!
    		return result;
    	}
    
    int main()
    {
    	int choice = 0;
    	printf("\n\nWelcome to the Temperature Converter\n");
    	do // repeat the program
    	{
    		printf("\nWould you like to convert singly or incrementally?\n");
    		printf("1. Singly\t2. Incrementally\t3. Exit ");
    		scanf("%d", &choice);
    
    		// one time declaration
    		int fahreneit = 0, celsius = 0;
    
    		if (choice == 1) {
    			int choicetwo = 0;
       
       			printf("\nIn which direction would you like to convert?\n");
    			printf("1. Celsius => Fahrenheit\t2. Fahrenheit => Celsius");
    			scanf("%d", &choicetwo);
       
    			if (choicetwo == 1) {
    				printf("\nPlease enter a Celsius starting value: ");
    				scanf("%d\n", &celsius);
    				fahreneit = CelsToFahr(celsius);
    				printf("Your corresponding fahrenheit value: %d\n", fahrenheit);
    			}
       
    			else if (choicetwo == 2) {
    				printf("\nPlease enter a Fahrenheit starting value: ");
    				scanf("%d\n", &fahrenheit);
    				celsius = FahrToCels(fahreneit);
    				printf("Your corresponding celsius value: %d\n", celsius);				
    			}
    			else {
    				printf("Wrong choice: %d",choichetwo);
    			}
    		}
       		else if (choice == 2) 
    		{
    			int lower, upper, step;
       
    			printf("\nPlease enter a lower limit: ");
    			scanf("%d", &lower);
    			printf("Please enter an upper limit: ");
    			scanf("%d", &upper);
    			printf("Please enter a step size: ");
    			scanf("%d", &step);
       
    			while (fahrenheit <= upper) 
    			{
    				celsius = FahrToCels(fahreneit);
    				printf("%d\t%d\n", fahrenheit, celsius);
    				fahrenheit = fahrenheit + step;
    			}
       			printf("\n");
    		}
    		else {
    			printf("Wrong choice:\t%d\d",choichetwo);
    		}
    		//program will stop only if we insert choiche number 3!
    	} while (choice != 3);
    	
    	printf("\nProgram will now exit");
    	return 0;
    }
    
     
  5. macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #5
    Hey Lee, when demonstrating how to use code tags, you can use the [plain] tag and it's closing tag with the slash to wrap the code tags. Therefore, you can say "please use the [code] and [/code] tags".
    :)

    (I wasn't sure how to code an ending noparse tag, as that would have turned parsing back on, and defeated my effects...)
     
  6. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #6
    Ah, sweet. Is noparse even in the editing palette? If not, how did you divine this functionality?

    -Lee
     
  7. macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #7
    It's a vBulletin thing. Lots of boards use the same software.
     
  8. thread starter macrumors member

    Joined:
    Aug 23, 2006
    Location:
    Downey, CA
    #8
    Thanks, but...

    Okay, what you did definitely works, but I don't understand what the meaning of what comes after main is. Could you explain? Also, what do you mean by saying that I was looking for a signed integer and a newline? What is fflush? Thanks a lot for your help, by the way.
     
  9. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #9
    Code:
    int main(int argc, char *argv[])
    Is the "standard" signature of the main function.

    Code:
    int main(void)
    Is also valid if you have no parameters. I prefer the prior because even if it's just for debugging, you might want to pass in some arguments to alter behavior. It's not always required, but that's just what i "default" to for the signature of main. The first int argument is the count of the number of command line parameters that have been passed to the application, and the second char ** is an array of char *s containing each of the parameters' value.

    From the scanf manpage:
    So:
    Code:
    scanf("%d\n", &fahrenheit);
    
    Will match an integer, a newline, then stop when it gets another input character. It won't get another input character until you press return again, so that's why you were having to press return twice.

    From the fflush man page:
    Essentially this ensures that a stream doesn't have any buffered output left, so things appear when and in some cases in the order you intend.

    -Lee
     
  10. thread starter macrumors member

    Joined:
    Aug 23, 2006
    Location:
    Downey, CA
    #10
    Thanks so much.

    Hey, Lee. You've helped a lot; that all makes sense now. Thanks a million.
     

Share This Page