Thread: What's wrong with my code (HELP)

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    19

    Question What's wrong with my code (HELP)

    hi, can you guys help me out with this portion of code. I don't know what's wrong with it.
    Code:
    #include <stdio.h>
    #include <math.h>
    
    main()
    {
      int count;
      float ctr,a;
      char x,s,S,c,C,q,Q;
    
      do{
        printf("(S)ine, (C)osine, or (Q)uit: ");
        scanf("%c", &x);
        if(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q')
          printf(" -- Illegal Input!\n");
      } while(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q');
    }
    it is supposed to print out this:
    Code:
    (S)ine, (C)osine, or (Q)uit: x
     -- Illegal Input!
    (S)ine, (C)osine, or (Q)uit:
    but it prints this out:
    Code:
     (S)ine, (C)osine, or (Q)uit: x
     -- Illegal Input!
    (S)ine, (C)osine, or (Q)uit:  -- Illegal Input!
    (S)ine, (C)osine, or (Q)uit:
    it prints out an extra line of sine, cosine, or quit with the illegal input statement after that. What did i do wrong? Help!!

  2. #2
    ~viaxd() viaxd's Avatar
    Join Date
    Aug 2003
    Posts
    246
    What did i do wrong?
    you used scanf()
    FAQ
    :wq

  3. #3
    Registered User
    Join Date
    Apr 2004
    Posts
    19
    i still don't get it. what can i do/change/add to the code?

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Well, a quick fix would be:
    Code:
     {
       printf(" -- Illegal Input!\n");
       while (getchar() != '\n');
     }
    Also, check the return from scanf() to ensure if read something OK:
    Code:
     if (scanf("%c", &x) != 1)
     {
       /* Error */
     }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #5
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Read the FAQ that viaxd linked for you. The first scanf() is leaving \n on the buffer so the next time through the loop it thinks you entered a blank line.
    If you understand what you're doing, you're not learning anything.

  6. #6
    Registered User
    Join Date
    Jul 2004
    Posts
    101
    The problem is not necessarily with scanf, but character input in general. When you ask an interactive user to enter a single character, two are actually placed on the input stream. The first is the character that the user typed and the second is the newline character created when the user pressed Enter. Your code does not account for the newline character and simply treats it as normal input.

    A quick and dirty solution is to simply ask for another character from the stream and discard it.
    Code:
    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
      char x;
    
      do{
        printf("(S)ine, (C)osine, or (Q)uit: ");
        scanf("%c", &x);
        getchar();
        if(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q')
          printf(" -- Illegal Input!\n");
      } while(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q');
    
      return 0;
    }
    However, this simply fixes the symptom and not the problem. A decidedly better solution is to work at the line level rather than the character level when dealing with streams.
    Code:
    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
      char x[BUFSIZ];
    
      do{
        printf("(S)ine, (C)osine, or (Q)uit: ");
        if (fgets(x, sizeof x, stdin) == NULL) {
          break;
        }
        if(x[0]!='s' && x[0]!='S' && x[0]!='c' && x[0]!='C' && x[0]!='q' && x[0]!='Q')
          printf(" -- Illegal Input!\n");
      } while(x[0]!='s' && x[0]!='S' && x[0]!='c' && x[0]!='C' && x[0]!='q' && x[0]!='Q');
    
      return 0;
    }
    This way you avoid leaving unwanted characters in the stream and you can also improve error handling by saving an entire input line in memory for multiple parsing.

  7. #7
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    to make the large if() and while() statements easier to read and work with, you may want to change them to a switch statement for x.

  8. #8
    Registered User
    Join Date
    Jul 2004
    Posts
    101
    Quote Originally Posted by Draco
    to make the large if() and while() statements easier to read and work with, you may want to change them to a switch statement for x.
    Or better yet, modularize each operation into a specialized function so a proper solution can be used without cluttering the main function.
    Code:
    #include <ctype.h>
    #include <math.h>
    #include <stdio.h>
    
    #define PROMPT "(S)ine, (C)osine, or (Q)uit: "
    
    int getOpt(const char *prompt);
    int isValid(char item, const char *options);
    
    int main()
    {
      int x;
    
      while ((x = getOpt(PROMPT)) != EOF && !isValid(x, "SCQ")) {
        printf(" -- Illegal Input!\n");
      }
    
      return 0;
    }
    
    int getOpt(const char *prompt)
    {
      char buffer[BUFSIZ];
    
      fputs(prompt, stdout);
      fflush(stdout);
      if (fgets(buffer, sizeof buffer, stdin) == NULL) {
        return EOF;
      }
    
      return buffer[0];
    }
    
    int isValid(char item, const char *options)
    {
      while (*options != '\0') {
        if (*options == toupper((unsigned char)item)) {
          return 1;
        }
        ++options;
      }
    
      return 0;
    }

  9. #9
    Registered User
    Join Date
    Apr 2004
    Posts
    19
    Code:
    #include <stdio.h>
    #include <math.h>
    
    main()
    {
      int count;
      float ctr,a;
      char x,s,S,c,C,q,Q;
    
      do{
        do{
          printf("(S)ine, (C)osine, or (Q)uit: ");
          scanf("%c", &x);
          if(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q')
            printf(" -- Illegal Input!\n");
          while(getchar() != '\n');
        } while((x!='s') && (x!='S') && (x!='c') && (x!='C') && (x!='q') && (x!='Q'));
    
    
        switch(x){
        case 's':
        case 'S':
          printf("   Enter starting value: ");
          scanf("%f", &a);
          for(count = 0; count < 10; count++)
            {
              for(ctr = a; ctr < a+.09; ctr += 0.01)
                printf("%1.3f ", sin(ctr));
              a += .1;
              printf("\n");
            }
          printf("%1.3f\n", sin(a));
          break;
        case 'c':
        case 'C':
          printf("   Enter starting value: ");
          scanf("%f", &a);
          for(count = 0; count < 10; count++)
            {
              for(ctr = a; ctr < a+.09; ctr += 0.01)
                printf("%1.3f ", cos(ctr));
              a += .1;
              printf("\n");
            }
          printf("%1.3f\n", cos(a));
          break;
        }
      } while(x!='q' && x!='Q');
      printf(" -- Goodbye\n");
    }
    here is all my code. i tried using the things you guys posted but i still got the same error.

  10. #10
    Registered User
    Join Date
    Jul 2004
    Posts
    101
    Try using the same solution after every call to scanf and see if the problem persists. scanf is a very complex function that is difficult to use properly even for experienced programmers. Once again I highly recommend tossing it in favor of fgets and a parsing scheme such as sscanf.

  11. #11
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Code:
      if(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q')
      {
        printf(" -- Illegal Input!\n");
        while(getchar() != '\n');
      }
    but the other solutions are better...

    [edit]
    Actually, that doesn't make a lot of difference. Here's the output I get from your code:
    Code:
     (S)ine, (C)osine, or (Q)uit: x
      -- Illegal Input!
     (S)ine, (C)osine, or (Q)uit: x
      -- Illegal Input!
     (S)ine, (C)osine, or (Q)uit: a
      -- Illegal Input!
     (S)ine, (C)osine, or (Q)uit: q
      -- Goodbye
    What's wrong with that?
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  12. #12
    Registered User
    Join Date
    Apr 2004
    Posts
    19
    Quote Originally Posted by Hammer
    Code:
      if(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q')
      {
        printf(" -- Illegal Input!\n");
        while(getchar() != '\n');
      }
    but the other solutions are better...

    [edit]
    Actually, that doesn't make a lot of difference. Here's the output I get from your code:
    Code:
     (S)ine, (C)osine, or (Q)uit: x
      -- Illegal Input!
     (S)ine, (C)osine, or (Q)uit: x
      -- Illegal Input!
     (S)ine, (C)osine, or (Q)uit: a
      -- Illegal Input!
     (S)ine, (C)osine, or (Q)uit: q
      -- Goodbye
    What's wrong with that?
    if you input "s" or "c" and then input a number, it prints out the table but then it also prints out "(S)ine, (C)osine, or (Q)uit: -- Illegal Input" and then it waits for you to press enter and then it finally re-enters the loop. i have to find a way to get rid of the first message. It should restart the loop without the message that i just wrote.

  13. #13
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Do this after every scanf():
    while(getchar() != '\n');
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  14. #14
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    The problem is not necessarily with scanf, but character input in general. When you ask an interactive user to enter a single character, two are actually placed on the input stream. The first is the character that the user typed and the second is the newline character created when the user pressed Enter. Your code does not account for the newline character and simply treats it as normal input
    Not trolling. but isn't that a problem with scanf then? thats why you clear the buffer if you use it. if you put a string in it would it not keep the '\n' in it as well? thats the problem with scanf. it keeps garbege in the buffer no. ex:
    PHP Code:
    #include <stdio.h>
    #define SIZE 10
    int main(void){
        
    char word[SIZE];
        
    scanf("%s"word);
        
    printf("entered %s"word);
        
    getchar(); //this one handles the '\n'
        
    getchar(); //this one waits for input to exit
        
    return 0;
        } 
    also to the original poster. along with the FAQ here is another answer as to why not to use scanf or at least if your going to use it. use it properly. like checking its return value and such.
    cheers.
    Last edited by caroundw5h; 08-10-2004 at 08:46 PM. Reason: forgot to put an ex.
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  15. #15
    Im a Capricorn vsriharsha's Avatar
    Join Date
    Feb 2002
    Posts
    192

    Smile A Cleaner way...

    Quote Originally Posted by n00by
    hi, can you guys help me out with this portion of code. I don't know what's wrong with it.
    Code:
    #include <stdio.h>
    #include <math.h>
    
    main()
    {
      int count;
      float ctr,a;
      char x,s,S,c,C,q,Q;
    
      do{
        printf("(S)ine, (C)osine, or (Q)uit: ");
        scanf("%c", &x);
        if(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q')
          printf(" -- Illegal Input!\n");
      } while(x!='s' && x!='S' && x!='c' && x!='C' && x!='q' && x!='Q');
    }
    it is supposed to print out this:
    Code:
    (S)ine, (C)osine, or (Q)uit: x
     -- Illegal Input!
    (S)ine, (C)osine, or (Q)uit:
    but it prints this out:
    Code:
     (S)ine, (C)osine, or (Q)uit: x
     -- Illegal Input!
    (S)ine, (C)osine, or (Q)uit:  -- Illegal Input!
    (S)ine, (C)osine, or (Q)uit:
    it prints out an extra line of sine, cosine, or quit with the illegal input statement after that. What did i do wrong? Help!!

    Hi, this might be another alternative...

    Code:
    #include<stdio.h>
    
    int main()
    {
    	char ch;
    	do
    	{
    		printf("(S)ine (C)os (Q)uit : ");
    		scanf("%c%*c",&ch);
    		switch(ch)
    		{
    			case 's':
    			case 'S':
    				printf("Sine Function\n");
    				break;
    			case 'c':
    			case 'C':
    				printf("Cos Function\n");
    				break;
    			case 'q':
    			case 'Q':
    				exit(0);
    			default:
    				printf("Invalid Input\n");
    		}
    	}while(1);
    	return 0;
    }
    Try out.....

    -Harsha.
    Help everyone you can

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. what is wrong in this simple code
    By vikingcarioca in forum C Programming
    Replies: 4
    Last Post: 04-23-2009, 07:10 AM
  2. what is wrong with this code please
    By korbitz in forum Windows Programming
    Replies: 3
    Last Post: 03-05-2004, 10:11 AM
  3. I cant find what is wrong with this code
    By senegene in forum C Programming
    Replies: 1
    Last Post: 11-12-2002, 06:32 PM
  4. Anyone see what is wrong with this code?
    By Wise1 in forum C Programming
    Replies: 2
    Last Post: 02-13-2002, 02:01 PM
  5. very simple code, please check to see whats wrong
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 10-10-2001, 12:51 AM