Using scanf() only
Using just scanf() to achieve this requires a certain amount of jiggery-pokery. It isn't the best way to code it, but…
#include <stdio.h>
int main(void)
{
char alo0;
char alo1;
char alo2;
char alo3;
printf("enter 3 characters: ");
while (scanf(" %c %c %c%c", &alo0, &alo1, &alo2, &alo3) == 4 &&
alo3 != '\r' && alo3 != '\n')
{
char buffer[4096];
if (scanf("%4095[^\n]", buffer) == EOF)
break;
printf("too long\n");
printf("enter 3 characters: ");
}
printf("Got [%c][%c][%c]\n", alo0, alo1, alo2);
return 0;
}
The while() condition uses scanf() to read four characters, skipping white space before the first three. Note that it is OK to put newlines in between characters; scanf() doesn't care. If you want line-based input, scanf() is simply the wrong tool for the job! However, assuming that 4 characters are read and the fourth is neither carriage return nor newline, then the code uses:
char buffer[4096];
if (scanf("%4095[^\n]", buffer) == EOF)
break;
to read any characters up to, but not including, a newline. It doesn't mind if there are no such characters so scanf() returns 0. The code then prompts you to enter the correct data and goes around to the main scanf(). This skips the newline that was left behind and then looks for three characters again.
When the while loop exits, it could be because it got three characters and a newline, or because it got fewer characters and EOF, or because the clean-up scanf() detected EOF. The code doesn't attempt to distinguish between these (but it should) and simply prints out three values. Fixing that is not dreadfully hard; simply assign the return from each scanf() to a variable and then test that after the loop:
int rc;
while ((rc = scanf(…)) == 4 && …)
{
…
if ((rc = scanf(…)) == EOF)
break;
…
}
if (rc == 4)
printf(…);
else
printf("Didn't get 3 characters as requested\n");
Using fgets() for line input
Personally, I think it is easier/better to use fgets() and sscanf() like this:
#include <stdio.h>
int main(void)
{
char alo0;
char alo1;
char alo2;
char alo3;
char buffer[4096];
int rc = 0;
printf("enter 3 characters: ");
while (fgets(buffer, sizeof(buffer), stdin) != 0 &&
(rc = sscanf(buffer, " %c %c %c%c", &alo0, &alo1, &alo2, &alo3)) == 4 &&
alo3 != '\r' && alo3 != '\n')
{
printf("too long\n");
printf("enter 3 characters: ");
// In case you get 4 characters but the 4th was not a newline
// and then you get EOF
rc = 0;
}
if (rc == 4)
printf("Got [%c][%c][%c]\n", alo0, alo1, alo2);
else
printf("Didn't get 3 characters as requested\n");
return 0;
}
This could report the string that was too long, or otherwise incorrect.
scanfreads 4 characters, and the secondscanfreads the other 3 characters and the newline. To avoid the problem, you should read a line withfgetsand then parse the line withsscanf.fgets()to read a line. Then usesscanf()to analyze the input. One advantage is you can include what they typed in the error message.