C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old May 11th, 2003, 07:06 AM
coredumped coredumped is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2001
Posts: 149 coredumped User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 49 m 47 sec
Reputation Power: 12
Reading only one character from stdin.

I'm coming off a 2-3 year hiatus from programming in C and trying to re-learn the language. Unfortunately, I have source from before, but no notes to learn from.

I'm having a problem with reading in a single character using scanf. I've also tried using getc. Basically, I have a little program like this one below:
Code:
int main(void)
{
  char myChar;
  unsigned char flag = 0;

  while (flag == 0)
  {
    printf("Enter character: ");
    scanf("%c",&myChar);

    printf("You entered '%c'.\n\n",myChar);

    if (myChar == 'q')
      flag = 1;
  }

  return (0);
}


Now, I have two problems with this code:
1) When you enter a single character, since the newline character is still in the input stream, the next time the loop comes around, '\n' is passed to scanf, which produces this result:
Code:
Enter Character: J
You entered 'J'

Enter Character: You entered '
'

Enter Character:

... not what I want. So how do I handle the newline character in this situation? I've tried this with getc as well and have the same results.

2) Besides the newline character, if the user enters more than one letter at the prompt, all the letters get processed through the loop. So you get something like:
Code:
Enter Character: hello
You entered 'h'

Enter Character: You entered 'e'

Enter Character: You entered 'l'

Enter Character: You entered 'l'

Enter Character: You entered 'o'

Enter Character: You entered '
'

Enter Character:

So I assume the two problems are related somehow, but I'm completely stumped as to how to resolve the problem. Looking back through my old source code I see things like:
Code:
myChar = getc(stdin);
fflush(stdin);


... which apparently worked (again, it was a while back, I can't remember for sure). But when I compile the same code on my system now, it fails. Doesn't make sense since I thought fflush was only for output buffers and not input ones.

Can anyone help me out understanding all this again? Anyone know of any good online 'C refreshers' I can visit?

Thanks,

- coredumped.

Reply With Quote
  #2  
Old May 11th, 2003, 01:22 PM
Jason Doucette's Avatar
Jason Doucette Jason Doucette is offline
jasondoucette.com
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2003
Location: Canada
Posts: 378 Jason Doucette User rank is Private First Class (20 - 50 Reputation Level)Jason Doucette User rank is Private First Class (20 - 50 Reputation Level) 
Time spent in forums: 7 h 23 m 8 sec
Reputation Power: 11
Try _getch()

I guess the reason the two functions you tried do not work is because they do not return control to the program after a character is entered (i.e. they wait for a CR - and thus, the CR is also placed into stdin). _getch() does not do this. Try this code for example:

Code:
char ch;
while (true)
{
	ch = _getch();
	if ((ch == '1') || (ch == '2') || (ch == '3') break;
} 
printf("%c\n\n",ch);
It will accept only the keys 1, 2, or 3 as input to break the loop. All other keys are ignored. And, the key is NOT printed to the screen automatically - it is done with the printf() call. I think this is sufficient for what you are looking for.

Reply With Quote
  #3  
Old May 11th, 2003, 05:10 PM
bass20 bass20 is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 16 bass20 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Try setting the terminal to non-canonical mode using the ioctl() system call (it'll read only one char at a time - I think it only works on UNIXes):

http://www.unidata.ucar.edu/cgi-bin/man-cgi?termio+7

An (incomplete) example:

main(){

struct termios oldT, newT;
char c;

ioctl(0,TCGETS,&oldT); /*get current mode

newT=oldT;
newT.c_lflag &= ~ECHO; /* echo off */
newT.c_lflag &= ~ICANON; /*one char @ a time*/

ioctl(0,TCSETS,&newT); /* set new terminal mode */

read(0,&c,1); /*read 1 char @ a time from stdin*/

ioctl(0,TCSETS,&oldT); /* restore previous terminal mode */

}

You may need to set two more flags to enable true non-canonical input, keep posting

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Reading only one character from stdin.

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap