Repetition in do{}while

This is a discussion on Repetition in do{}while within the C Programming forums, part of the General Programming Boards category; I googled for this stupid error, and have tried certain things, but can't figure out how to avoid the repetition ...

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    93

    Repetition in do{}while

    I googled for this stupid error, and have tried certain things, but can't figure out how to avoid the repetition of my main prompt in a do while loop.

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    #define MAX_SCORE  100
    #define MIN_SCORE  0
    #define TOTAL_ASSIGNMENT_MAX_SCORE 300
    
    void menu (void);
    float take_score (void);
    float final_score_calc (float x, float y, float z);
    char letter_grade (float x);
    float G_P_A (char x);
    void info_display (void);
    void print_scores (float x, char y, int z);
    
    int main () {
    
    //int total_assignments, midterm, final_exam, students, counter,GPA;
    //int A_Count=0, B_Count=0, C_Count=0, D_Count=0, F_Count=0, total_Grade_Count;
    //float final_score, total_final_score=0, A_Percentage, B_Percentage, C_Percentage, D_Percentage, F_Percentage;
    
    menu();
    return 0;
    
    
    
    /*
     total_final_score /= students;
     total_Grade_Count = A_Count + B_Count + C_Count + D_Count + F_Count;
    
     A_Percentage = (( float ) ACounter / total_Grade_Count) * 100;
     B_Percentage = (( float ) BCounter / total_Grade_Count) * 100;
     C_Percentage = (( float ) CCounter / total_Grade_Count) * 100;
     D_Percentage = (( float ) DCounter / total_Grade_Count) * 100;
     F_Percentage = (( float ) FCounter / total_Grade_Count) * 100;
    
     printf("\nStatistical result of your class:\n\n");
     printf("\n\tTotal Students Number:\t%d", students);
     printf("\n\tAverage score:\t%.2f",total_final_score);
     printf("\n\tTotal A grade: %d, percentage   %.2f%%", A_Count, A_Percentage);
     printf("\n\tTotal B grade: %d, percentage   %.2f%%", B_Count, B_Percentage);
     printf("\n\tTotal C grade: %d, percentage   %.2f%%", C_Count, C_Percentage);
     printf("\n\tTotal D grade: %d, percentage   %.2f%%", D_Count, D_Percentage);
     printf("\n\tTotal F grade: %d, percentage   %.2f%%\n", F_Count, F_Percentage);
    */
    }
    
    void menu (void) {
    
    	char c;
    	float final_score, total_final_score=0, average_final_score=0, high_score=-1, low_score=101;
    	float A_Percentage, B_Percentage, C_Percentage, D_Percentage, F_Percentage;
    	char grade;
    	int GPA, student_counter=0, ACounter=0, BCounter=0, CCounter=0, DCounter=0, FCounter=0, total_Grade_Count=0;
    
    	total_Grade_Count = ACounter + BCounter + CCounter + DCounter + FCounter;
    
    	A_Percentage = (( float ) ACounter / total_Grade_Count) * 100;
    	B_Percentage = (( float ) BCounter / total_Grade_Count) * 100;
    	C_Percentage = (( float ) CCounter / total_Grade_Count) * 100;
    	D_Percentage = (( float ) DCounter / total_Grade_Count) * 100;
    	F_Percentage = (( float ) FCounter / total_Grade_Count) * 100;
    	
    	
    	do{
    
    
    	printf("A/a  - Add a student's record\n");
    	printf("D/d - Display current statistical results\n");
    	printf("Q/q - Quit\n");
    	printf("\nPlease enter a key for one of the above options:");
    
    		c=getchar();
    		c=toupper(c);
    
    		switch (c) {
    
    		case 'A': 
    			
    				  final_score = take_score();
    				  grade = letter_grade(final_score);
    				  GPA = G_P_A(grade);
    				  print_scores(final_score, grade, GPA);
    
    				  student_counter ++;
    
    				  switch (grade) {
    
    				  case 'A': ACounter++;
    								break;
    
    				  case 'B': BCounter++;
    								break;
    
    				  case 'C': CCounter++;
    								break;
    
    				  case 'D': DCounter++;
    								break;
    
    				  case 'F': FCounter++;
    								break;
    
    				  }
    
    				  total_final_score += final_score;
    
    				  average_final_score = (total_final_score / student_counter);
    
    				  if (final_score > high_score)
    					  high_score = final_score;
    
    				  if (final_score < low_score)
    					  low_score = final_score;
    					  
    				
    				  break;
    
    		case 'D':  
    			
    				   printf("\nStatistical result of your class:\n\n");
    				   printf("\n\tTotal Students Number:\t%d", student_counter);
    				   printf("\n\tAverage score:\t%.2f",average_final_score);
    				   printf("\n\tHigh score:\t%.2f",high_score);
    				   printf("\n\tLow score:\t%.2f",low_score);
    				   printf("\n\tTotal A grade: %d, percentage   %.2f%%", ACounter, A_Percentage);
    				   printf("\n\tTotal B grade: %d, percentage   %.2f%%", BCounter, B_Percentage);
    				   printf("\n\tTotal C grade: %d, percentage   %.2f%%", CCounter, C_Percentage);
    			       printf("\n\tTotal D grade: %d, percentage   %.2f%%", DCounter, D_Percentage);
    				   printf("\n\tTotal F grade: %d, percentage   %.2f%%\n\n", FCounter, F_Percentage);
    				  
    				   break;
    
    		}
    
    	}while (c != 'Q');
    
    	printf("\nBye!\n\n");
    
    }
    
    float final_score_calc (float x, float y, float z) {
    
    	 float final_score;
    
    	 final_score = x /3.0* 0.3 + y * 0.3+ z* 0.4;
    
    	 return final_score;
    
     }
    
    float take_score (void) {
    
    	float total_assignments, midterm, final_exam, final_score;
    
      printf("\nEnter a student's total assignment, midterm and final exam scores:");
      scanf("%f %f %f", &total_assignments, &midterm, &final_exam);
    
      while (total_assignments > TOTAL_ASSIGNMENT_MAX_SCORE || total_assignments < MIN_SCORE)
    
      {
       printf("\nPlease re-enter total assignment score (0~300) :");
       scanf("%f", &total_assignments);
      }
    
    
      while (midterm > MAX_SCORE || midterm < MIN_SCORE)
    
      {
       printf("\nPlease re-enter midterm score (0~100) :");
       scanf("%f", &midterm);
      }
    
      while (final_exam > MAX_SCORE || final_exam <MIN_SCORE)
    
      {
       printf("\nPlease re-enter final exam score (0~100) :");
       scanf("%f", &final_exam);
      }
     
      final_score = final_score_calc (total_assignments, midterm, final_exam);
    
      return final_score;
    
     }
    
    char letter_grade (float x) {
    
    	float final_score = x;
    	
    	char grade;
    
    	if (final_score >= 90)
    		grade='A';
    
    	else if (final_score < 90 && final_score >= 80)
    		grade='B';
    
    	else if (final_score < 80 && final_score >=70)
    		grade='C';
    
    	else if (final_score < 70 && final_score >= 60)
    		grade='D';
    
    	else if (final_score < 60)
    		grade='F';
    
    	return grade;
    
    }
    
    float G_P_A (char x) {
    	
    
    	float GPA;
    
    	switch ( x ) {
     case 'A': GPA = 4; 
          break;
    
     case 'B': GPA = 3; 
          break;
    
     case 'C': GPA = 2; 
          break;
    
     case 'D': GPA = 1; 
          break;
    
     case 'F': GPA = 0; 
          break;
    
     }
    
    	return GPA;
    
    }
    
    void print_scores (float x, char y, int z) {
    
    	printf("final_score:   %.2f  letter grade:%c  GPA:%d\n\n", x, y, z);
    
    }
    When you compile it you will probably notice that the high/low scores and the percentages need work, but I am still working on those. I should be able to figure them out, but I don't know what to do with the do-while.

    Any hints, or pointers in the right direction would be extremely helpful.

    Thanks.
    Last edited by Beast(); 06-16-2004 at 12:58 AM. Reason: Spelled repetition like a bum

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    but can't figure out how to avoid the repition of my main prompt in a do while loop.
    Something like this? Though repeating the menu is a good thing IMO
    Code:
    printf("A/a  - Add a student's record\n");
    printf("D/d - Display current statistical results\n");
    printf("Q/q - Quit\n");
    printf("\nPlease enter a key for one of the above options:");
    
    do{

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Oh yea, the main point of it is to repeat the menu, so they can input whatever they want once again...but it just does it twice after I input something.

    I want it to reappear, but not twice like it is now.

  4. #4
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Most likely something is being left in the input buffer which is causing the loop to be executed twice.

    Edit:

    Code:
    c=getchar();
    For this to work you have to hit a key and then hit enter. So say you hit a, enter. The input buffer would look something like:
    Code:
     'a', '\n'
    So the getchar() will pull the 'a' out of the buffer but the '\n' is still hanging out in there. So after the loop gets done processing 'a' it goes back to the getchar(). Well all getchar() requires is that there is a '\n' in the buffer for it to exexute so it'll get the '\n' out of the buffer. Then the loop executes for '\n'.

    That is why you are seeing the menu twice in a nutshell.

    <austin> Look at me I'm in a nutshell. How did I get in a nutshell?</austin>
    Last edited by Thantos; 06-16-2004 at 01:13 AM.

  5. #5
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Quote Originally Posted by Thantos
    Most likely something is being left in the input buffer which is causing the loop to be executed twice.

    Edit:

    Code:
    c=getchar();
    For this to work you have to hit a key and then hit enter. So say you hit a, enter. The input buffer would look something like:
    Code:
     'a', '\n'
    So the getchar() will pull the 'a' out of the buffer but the '\n' is still hanging out in there. So after the loop gets done processing 'a' it goes back to the getchar(). Well all getchar() requires is that there is a '\n' in the buffer for it to exexute so it'll get the '\n' out of the buffer. Then the loop executes for '\n'.

    That is why you are seeing the menu twice in a nutshell.

    <austin> Look at me I'm in a nutshell. How did I get in a nutshell?</austin>
    FOCKING genius!

    Lol thanks man, seems simple now but I hadn't realized back then.

  6. #6
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Why won't a case '\n': or a default: catch the newline in the switch?

    Just ignores it and keeps doing it.

    I am able to solve this through if statements, but am curious as to why the switch statement goes to hell.

  7. #7
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,812
    the switch statment is not catching the '\n' the '\n' is in the input buffer so when your looping back to your getchar() its reading that '\n' the '\n' has nothing to do with the variable at hand
    Woop?

  8. #8
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    This is the same problem I had in my previous question with scanf, where Quzah told me to use getchar().

    It being \n again, makes much sense. Now I understand what he meant by a newline in the input stream.

    But, in this do-while with a switch, it doesn't seem to go away. I'm going to experiment with brackets or something, the program just laughs at me and keeps going through.

  9. #9
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,812
    well if you don't want to run into this problem at all you could always flush the input buffer using fflush(stdin) j/k guys.
    Check out this page.
    http://faq.cprogramming.com/cgi-bin/...&id=1043284392
    Woop?

  10. #10
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Ah thanks man, I hadn't even seen your post up above.

  11. #11
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Ok haha, I read why the flush isn't such a good idea.

    My code still repeats when I use a do-while and a switch statement.

    Would it be possible to have a nested while loop in the do-while loop to tell it to not go through when it is '\n'? I can't seem to pull that one off either.

  12. #12
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    try:
    Code:
    while ( (c=getchar()) == '\n');

  13. #13
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Quote Originally Posted by Thantos
    try:
    Code:
    while ( (c=getchar()) == '\n');
    Actually bro, that exact same line of code you just posted, is what I have put in my code, in various forms, and various places, and it still goes through or it messes up the prompt.

    This \n is a son of a I am sillyI am sillyI am sillyI am sillyI am silly.

  14. #14
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Hmm I copied your code and made that change and only time I got a duplicate is when I enter something such as "100 100 100 " (notice the two extra spaces)

    So you could always encapulate it in one more level: add
    Code:
    int valid = 1;
    and then change the loop as such: (sorry for lack of formatting)
    Code:
    do {
      printf("A/a  - Add a student's record\n");
      printf("D/d - Display current statistical results\n");
      printf("Q/q - Quit\n");
      printf("\nPlease enter a key for one of the above options:");
      do {
        valid = 1;
        c=getchar();
        c=toupper(c);
        switch(c) {
          /* blah blah */
          case 'Q': break;
          default: valid = false; break;
        }
      }while(!valid);
    }while (c != 'Q');

  15. #15
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,812
    actully i found a rather simple answer now that i think about it just do this
    Code:
    		getchar();
    
    	}while (c != 'Q');
    
    	printf("\nBye!\n\n");
    
    }
    Woop?

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

Similar Threads

  1. sentinel controlled repetition example
    By droseman in forum C Programming
    Replies: 7
    Last Post: 09-26-2008, 03:17 AM
  2. repetition with the "for" structure
    By Lillian in forum C Programming
    Replies: 3
    Last Post: 10-19-2002, 10:28 PM
  3. Repetition of a line
    By niroopan in forum C++ Programming
    Replies: 1
    Last Post: 09-15-2002, 05:44 PM
  4. Controlling Repetition in a Structure
    By Silence in forum C Programming
    Replies: 2
    Last Post: 08-23-2002, 06:35 PM
  5. repetition and selection- can anyone help?
    By Tarls in forum C++ Programming
    Replies: 2
    Last Post: 03-29-2002, 10:18 PM

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