• C

Simple scanf question

:
:
char a;
:
:

scanf("%c",&a);
The above will of course read in a char variable but how to check for instance one key in more than 1 character eg. 'ab'. If he enters more than 1 character, i should flag an error. Please give me the example code.
LVL 33
hongjunAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

rolliCommented:
Function strlen(a) of the standard library returns the lenght of his argument a of a character chain excluding the final '\0'.
  So if you want to ask for the lenght, an example that will help you would be:
/* strlen: returns lenght of a */
int strlen(char[a])
{
  int i;
  i=0;
  while (a[i] != '/0')
     ++i;
  return i;
}

(than of course if i > 1 post your error message!)

This should help!
hongjunAuthor Commented:
Is there any other method without using strings?
yogi_bansalCommented:
the following though uses strings , but doesn't use
string library... ,
might help


void input(void)
{
  char inp_str[10]; /*let's assume the user will not enter
more than 10 characters any time. */

  scanf("%s",inp_str);
  if(inp_str[1]!='\0')  
    printf("\n invalid input ");
 
  /* inp_str[0] has ur required input character */

}
Ensure Business Longevity with As-A-Service

Using the as-a-service approach for your business model allows you to grow your revenue stream with new practice areas, without forcing you to part ways with existing clients just because they don’t fit the mold of your new service offerings.

hongjunAuthor Commented:
Thank you yogi_bansal for replying to this question. Your proposed answer can definitely work only if your assumption is true. However, what if the user enters more than the maximum characters and this might cause memory core dump.
ozoCommented:
scanf("%2s",inp_str);
/* although it would also accept 'a ' */
TriskelionCommented:
You should not allow the user to enter data larger than the expected container.  You will always have memory problems if your code allows more than one character to get into a single character container.  Therefore, there is no safe way to use scanf with a single character container to detect more than one character.  You can use more character variables in your scanf and check them for NULL or
you can use _kbhit() (DOS) or its equivalent in other operating systems to detect the keyboard hit and follow it up with _getch() to put the character into the variable.
#include <conio.h>
#include <stdio.h>
void main(void)
{
   char cData;
   while (!_kbhit){/*do nothing*/}
   cData = (char)_getch();
   printf("You pressed the '%c' key", cData);
}
hongjunAuthor Commented:
I rejected Triskelion's answer because my Unix system for compiling C does not have the conio.h library.
graham_kCommented:
maybe you don't need to worry with such complicated stuff?

Maybe you don't want to use scanf(); what's wrong with getc() ?

If the user eneters two or more chars, where is the problem? You deal with exactly one. The problem might be when you next call getc() because those characters are still in the input buffer. So, even if the user gives no input, getc() would still return those previously enetered cahracters, because they were buffered.

So, a simple solution seems to be to flush the buffer before reading.  I don't find a way to flush a single input buffer (stdin; e.g using fflush()), but flushall() from <stdio.h> shoudl work.  It writes all unwritten output on output files & clears the input buffer.

So, always using flushall() before getc() should work;

#include <stdio.h>

int main(int argc, char *argv[])
{
  char a;
  /* lots of code ... */
  flushall();
  printf("Please enter exactly one character : \n");
  a = getc();  

  /* lots more code - don't forget to flushall before your next read - it's good practise */
}
rbrCommented:
I can give you a general input function which should be able to handle all you input stuff but not for 10 points. If you want to do it youself look at the ioctl and read functions in UNIX.
kariboeCommented:
use getch(); and echo the character to the screen if necessary (or take a look at getchar())
CMathewsCommented:
Do you want a single character followed by a line terminator (CANONICAL), or do you want a single character to be returned without having to enter a line terminator (NON-CANONICAL) ?

There are a number of ways of doing this but what are you trying to achieve ?
hongjunAuthor Commented:
I am trying only for validation purpose.
lewis_looCommented:
use getc or readkey to do that job for eg:

define TRUE 1
define FALSE 0

 char a;
 int i,n;
{
 i=FALSE;
 n=1;
 do
 {
  a=getch();
  if (n>1)
  {
   printf ("more than one character");
   i=TRUE;
  }
  else
    printf("%c",a);
  n++;
 }while (i==TRUE);
}
hongjunAuthor Commented:
lewis_loo won't the proposed answer result in endless loop since i never reset to FALSE.
MithanderCommented:
This should work, but I have no compiler to test it right now:

char a;
scanf("%c",&a);
if(kbhit())
{
  printf("You entered more than one letter.\n");
}
while(kbhit())
  getch();

The last two lines clear out the keyboard buffer.  If you don't want to do that then you can take them off.
hongjunAuthor Commented:
Mithander: Must I include other header files besides stdio.h to run your example smoothly?
Because I have some problems running your program.
ceroCommented:
Hey, u can use gets or getch or getche instead, why exactly do u want to use scanf.
With scanf u can´t do what you are trying.

u have to use getch
char a;
char temp[2],car;
i = 0;
while(i<1) {
  getche(temp[i]);
  i++;
}
temp[1]=0;
a = temp[0];
and OK.
MithanderCommented:
#include <conio.h>
MithanderCommented:
I just tested it, and my example dosn't work. Sorry.
hongjunAuthor Commented:
Why do you have to set temp[1] to 0 yourself? You didn't flag any error if the user enters more than one input.
kryptixCommented:
You can use getch() if you include curses.h

#include<curses.h>

compile your program with -lcurses
cc <filename> -lcurses
andrewqiuCommented:
Assume you are accepting input from keyboard:

char  line[81],c;

scanf("%[^\n]%c", line,&c);

if(strlen(line)>1) printf("error");
hongjunAuthor Commented:
Allocating an array to 81 character is simply mean wasting of memory. Yeah, I know it will work because the maximum number of characters on one line is 81.
baegCommented:
Stupid, stupid, stupid,  See the help how to get a F..ing character and convert where to want, Sorry

Do you use Borland, or MS compiler, because kbhit() function is only in Borland C, But you can use getch() to fill a buffer, and when the user press the enter then U must terminate the string with 0



CMathewsCommented:
Most people are assuming that hongjun is using a PC, but from a previuos comment it looks as if this solution is required on a UNIX system.  Is this so ? Or does the solution have to work for PC also ?
DVBCommented:
Try getch() with <curses.h> in unix.
hongjunAuthor Commented:
i am using unix. Unfortunately, the compiler do not have conio.h
woregulCommented:
Should the program allow the user to enter one character and then press return(enter) as valid input or just accept the one character typed without a return?
rolliCommented:
cut it out!
hongjunAuthor Commented:
User should enter a character and then a return key.
woregulCommented:
The following program accepts a single character and a return as valid input. The character cannot be another return. Input after the return characer is ignored and removed from the input buffer with an fflush. The program will keep trying to get valid input. If you want to only give the user one chance or a certain number of chances, change the else clause (the only one in the program).

#include <stdio.h>

main()
{
    char cFirst = 0;
    char cSecond = 0;
    int  bInputValid = 0;

    while (!bInputValid)
    {
        printf("\nNOTE: Hit Ctrl-D if the prompt stops responding.\n");
        printf("Enter one character and press return:");

        if ((cFirst = getc(stdin)) == EOF)
        {
            printf("Error reading input.\n");
            fflush(stdin);
            continue;
        }
        if ((cSecond = getc(stdin)) == EOF)
        {
            printf("Error reading input.\n");
            fflush(stdin);
            continue;
        }

        fflush(stdin);

        if ( cFirst != '\n' && cSecond == '\n' )
        {
            bInputValid = 1;
        }
        else
        {
            printf("Invalid input.\n");
        }
    }

    printf("\nYou entered %c.\n", cFirst);

}

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
hongjunAuthor Commented:
Thanks woregul for your excellent answer. Sorry for the delay in evaluation of your answer because exam period is coming. No time to surf. By the way, I have increased point for this question from 10 to 30. I also graded you A: Excellent!!! Keep it up.
MoondancerCommented:
This question was awarded, but never cleared due to the JSP-500 errors of that time.  It was "stuck" against userID -1 versus the intended expert whom you awarded.  This corrects that and the expert will now receive these points, all verified.
Moondancer
Moderator @ Experts Exchange
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.