C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 08-10-2004, 02:33 PM   #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!!
n00by is offline   Reply With Quote
Old 08-10-2004, 02:46 PM   #2
~viaxd()
 
viaxd's Avatar
 
Join Date: Aug 2003
Posts: 246
Quote:
What did i do wrong?
you used scanf()
FAQ
__________________
:wq
viaxd is offline   Reply With Quote
Old 08-10-2004, 06:41 PM   #3
Registered User
 
Join Date: Apr 2004
Posts: 19
i still don't get it. what can i do/change/add to the code?
n00by is offline   Reply With Quote
Old 08-10-2004, 06:46 PM   #4
End Of Line
 
Hammer's Avatar
 
Join Date: Apr 2002
Posts: 6,240
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]
Hammer is offline   Reply With Quote
Old 08-10-2004, 06:46 PM   #5
Gawking at stupidity
 
Join Date: Jul 2004
Posts: 2,324
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.

Ignore any "advice" esbo tries to give you. It's wrong.
itsme86 is offline   Reply With Quote
Old 08-10-2004, 06:50 PM   #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.
Princeton is offline   Reply With Quote
Old 08-10-2004, 07:09 PM   #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.
Draco is offline   Reply With Quote
Old 08-10-2004, 07:14 PM   #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;
}
Princeton is offline   Reply With Quote
Old 08-10-2004, 07:15 PM   #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.
n00by is offline   Reply With Quote
Old 08-10-2004, 07:23 PM   #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.
Princeton is offline   Reply With Quote
Old 08-10-2004, 07:34 PM   #11
End Of Line
 
Hammer's Avatar
 
Join Date: Apr 2002
Posts: 6,240
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]
Hammer is offline   Reply With Quote
Old 08-10-2004, 07:46 PM   #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.
n00by is offline   Reply With Quote
Old 08-10-2004, 07:50 PM   #13
End Of Line
 
Hammer's Avatar
 
Join Date: Apr 2002
Posts: 6,240
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]
Hammer is offline   Reply With Quote
Old 08-10-2004, 08:40 PM   #14
Registered User
 
caroundw5h's Avatar
 
Join Date: Oct 2003
Posts: 719
Quote:
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.
__________________
When the concrete cases are understood the abstractions are readily made

Last edited by caroundw5h; 08-10-2004 at 08:46 PM. Reason: forgot to put an ex.
caroundw5h is offline   Reply With Quote
Old 08-11-2004, 12:15 AM   #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
vsriharsha is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 08:06 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

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