scanf reads the wrong char - c

I need to write a program in C that let's the user choose to draw a rectangle square or print the board he made but everytime after the first input of a shape the program acts as if he entered an invalid character.
printf("please make you decision R-rectangle, S-square, E-end\n");
scanf("%c", &decision);
do
{
if (decision == 'R') {
printf("you chose rectangle! please enter the X start position, Y start position, hieght and width\n");
scanf("%d %d %d %d", &rectMat[0][rectCounter], &rectMat[1][rectCounter], &rectMat[2][rectCounter], &rectMat[3][rectCounter]);
if (rectCounter + 1 < MAX_RECT)
{
if (checkRECT(rectMat[0][rectCounter], rectMat[1][rectCounter], rectMat[2][rectCounter], rectMat[3][rectCounter], areaMat) == 1)
{
drawRECT(rectMat[0][rectCounter], rectMat[1][rectCounter], rectMat[2][rectCounter], rectMat[3][rectCounter], areaMat);
rectCounter++;
}
else
{
printf("we couldn't fit you rectangle\n");
}
}
else
{
printf("you have too many rectangles\n");
}
}
if (decision == 'S')
{
printf("you chose square! please enter the X start position, Y start position and size of the side\n");
scanf("%d %d %d", &sqrMat[0][rectCounter], &sqrMat[1][rectCounter], &sqrMat[2][rectCounter]);
if (sqrCounter<MAX_SQR)
{
if (checkSQR(sqrMat[0][rectCounter], sqrMat[1][rectCounter], sqrMat[2][rectCounter],areaMat)==1)
{
drawSQR(sqrMat[0][rectCounter], sqrMat[1][rectCounter], sqrMat[2][rectCounter], areaMat);
sqrCounter++;
}
else
{
printf("we couldn't fit your square\n");
}
}
else
{
printf("you have too many sqaures\n");
}
}
if (decision == 'P')
{
printArea(areaMat);
}
if (decision != 'E'&& decision != 'P'&& decision != 'S'&& decision != 'R')
{
printf("invalid entry\n");
}
printf("please make you decision R-rectangle, S-square, E-end\n");
scanf("%c", &decision);
} while (decision != 'E');

When you read characters using the "%c" format, it will read the next character in the input buffer, it will not skip any white-space. And when using scanf to read anything, the newline you enter to send the input to the program will also be sent, and added as a white-space character after the end of your input. Most formats do skip leading white-space (like for example the "%d" format), but the "%c" and "%[" formats do not.
When reading character it's almost always advisable to skip leading white-space, which is done by adding a space before the format, like e.g.
scanf(" %c", &decision);
// ^
// |
// Note space here
Also note that there is a difference between upper- and lower-case letters. 'R' != 'r'. Either check for both upper- and lower-case letters, or use toupper (or tolower) to convert.

you better off using getc() instad of scanf() since you're expecting a single char anyway

Related

scanf different position in the code in c [duplicate]

This question already has answers here:
problem in scanning character in C
(8 answers)
Closed 1 year ago.
int main()
{
char Operator;
int num1, num2, result;
/* printf("Enter operator: ");
scanf("%c", &Operator);*/
printf("Enter first and second value: ");
scanf("%d %d", &num1, &num2);
printf("Enter operator: ");
scanf("%c", &Operator);
if(Operator == '+')
{
result = num1 + num2;
printf("%d\n", result);
}
else if(Operator == '-')
{
result = num1 - num2;
printf("%d\n", result);
}
return 0;
}
I tried making a simple calculator, and I put scanf(the one that requests an Operator) where it is now, and it does not work. But if I put it where the comment is, above the "Enter first and second value" it then works. I would just like to know why does it work on one place and not the other.
Thanks in advance.
As pointed out in comments, Your first scanf is reading the integer values but it's not reading the newline in buffer. When you do scanf("%c", &Operator) again for taking character input, it reads that newline character still present in input buffer. To avoid this, you can use scanf(" %c", %Operator) instead which will discard all whitespace characters before matching character:
printf("Enter operator: ");
scanf(" %c", &Operator);
You can also use fgets() to read input into a string and then use sscanf() to read integers from string:
char input[100];
printf("Enter first and second value: ");
if (fgets(input, 100, stdin) == NULL) {
printf("No input provided!\n");
return -1;
}
if (strchr(input, '\n') == NULL) {
printf("Input Buffer Overflow\n");
return -1;
}
if (sscanf(input, "%d %d", &num1, &num2) != 2) {
printf("Error in reading characters\n");
return -1;
}
printf("Enter operator: ");
if (fgets(input, 100, stdin) == NULL) {
printf("No input provided!\n");
return -1;
}
if (strchr(input, '\n') == NULL) {
printf("Input Buffer Overflow\n");
return -1;
}
if (sscanf(input, "%c", &Operator) != 1) {
printf("Error in reading characters\n");
return -1;
}
From the Open Group Base Specifications Issue,
Input white-space characters (as specified by isspace()) shall be
skipped, unless the conversion specification includes a [, c, C, or n
conversion specifier.
%d format specifier will skip preceding input newline character (\n). That's why it works in the first case (case, where operator was read first) .
scanf leaves an newline character \n in the input buffer, after the first scanf.
The second scanf will read the extra \n from the input buffer to variable Operator. That's why it will not work.
Since the format specifier is %c, the newline character will not be skipped.
Solution : Use scanf(" %c", &Operator);. Add an extra space at the beginning.

Can scanf() function take single character value?

I was trying a simple C code and found out strange error. Here is the code. As soon as the first
scanf()
function is encountered, the compiler automatically skips it and move ahead. Why is that so?
#include<stdio.h>
#include<stdlib.h>
void main()
{
float base_cost, refresh_cost;
int ticket;
char coupon, refresh, circle;
printf("Enter number of tickets: ");
scanf("%d", &ticket);
if(ticket<5 ||ticket>40)
{
printf("Minimum of 5 and Maximum of 40 Tickets");
exit(0);
}
printf("Do you want refreshment?(Y/N): "); //Here compiler skips
scanf("%c", &refresh);
printf("Do you have coupon?(Y/N): ");
scanf("%c", &coupon);
printf("Enter circle: ");
scanf("%c", &circle);
if(circle!='k'||circle!='q' || circle!='K' || circle!='Q')
{
printf("Invalid Input");
exit(0);
}
else if(circle == 'k' || circle == 'K')
{
if(ticket > 20)
base_cost = (ticket*75.00) - 0.1*(ticket*75.00);
else if(coupon == 'y' || coupon == 'Y')
base_cost = (ticket*75.00) - 0.02*(ticket*75.00);
else
base_cost = ticket*75.00;
}
else if (circle == 'q' || circle == 'Q')
{
if(ticket > 20)
base_cost = (ticket*150.00) - 0.1*(ticket*150.00);
else if(coupon == 'y' || coupon == 'Y')
base_cost = (ticket*150.00) - 0.02*(ticket*150.00);
else
base_cost = ticket*150.00;
}
if (refresh == 'y' || refresh == 'Y')
{
refresh_cost = ticket * 50.00;
}
else
refresh_cost = 0.00;
printf("\nTotal cost: %0.2f", base_cost + refresh_cost);
}
I used the variable refresh in order to allow the user to have a choice, whether or not to insert elements i.e. Y or N.
Also, it looks like other scanf function with char as input are also been skipped.
But the compiler basically skips the third scanf function, the one that accepts the char, along with the while loop.
Unlike %d and %s, the %c conversion specifier does not skip over leading whitespace. What's happening is you have a stray newline in the input stream after the first scanf call to get the ticket number; that newline is read by the next scanf call and assigned to refresh.
To avoid this, put a blank space in front of the %c specifier:
scanf( " %c", &refresh );
That blank space tells scanf to skip over any leading whitespace. Do this for every %c that is meant to read a non-whitespace cparacter.

Scanf in visual studio not accepting multiple cases of characters

I'm creating a conversion project for letters/numbers ASCII table. My code is supposed to be 'interactive', so the user would type 'y' or 'n' to answer questions on the screen. However, it doesn't want to do this twice...
I have tried:
Just trying numbers instead of characters, but it's not exactly what I want
The %[\n]*c, and %[\n]c, and %[\n]*s ... technique but it doesn't help ;-;
Testing in a different project, but the only way I am able to do it is for multiple scanf()s to be in a row.
Here is the code:
printf("Would you like to convert a number today? \n");
printf("Please press Y or N \n");
scanf("%c", &input);
if (input == 'y' || input == 'Y') { //compare input if they said 'yes'
printf("\nThank you! \nWhat number?\n");
scanf("%d", &number);
flag = test(number);
if (flag == 0) { //if there is an equivalent letter
letter = conversion(number); //find the equivalent letter
printf("\nYour Number \t ASCII letter\n");
printf("%d\t %c\n", number, letter);
}
}
else if (input == 'n' || input == 'N') {
printf("\nWould you like to convert a letter instead? This time enter 0 or 1\!\n\n"); //problem here!!
printf("I wish I could say it was to \' Spice things up \' ...but it\'s not ;-; \n\n");
scanf("%d", &input2);
if (input2 == 0) { //this needs to be checking whether the user input Y/y
printf("Great choice adventurer!\n");
printf("What letter will it be today?\n\n");
//..I would go to a different funtion here ie: test2(letter)...
scanf("%d", &number); //I showed that it worked with multiple numbers, but I can't get this to work with multiple letters
printf("%d", number);
}
if (input2 == 1) { //this needs to be checking whether the user input N/n
printf("Difficult to please, I see...\n\n");
printf("I suggest you move on with that attitude!\n\n");
printf("Bye bye then\n");
}
}
else { //if they tried to break the code
printf("Sorry I did not recognise your command...please retry\n");
printf("Press Y or N next time!\n");
}
The first check works perfectly, I just want the second check to be like the first!
Some 'solutions' caused a overflow, which I don't want if possible
Even if someone could explain why this isn't working the way I intended would be very helpful!
I'm not sure what confuses you.
Use
char foo;
scanf(" %c", &foo);
for single characters, eg. letters and
int bar;
scanf("%d", &bar);
for numbers, integers. If you type a letter instead, scanf() will fail.
%[...] is for strings.
scanf() returns the number of successful conversions (or EOF), so for
int height;
int width;
scanf("%d %d", &height, &width);
it returns 2 if successful. It might return 1 if only height could be read.
So to check for errors on user input you should do:
int height;
int width;
if (scanf("%d %d", &height, &width) != 2) {
// handle the error, maybe exit the program.
}
Your code could look like that (without error handling):
#define _CRT_SECURE_NO_WARNINGS // you said Visual Studio? Without it you should get
// warnings about some functions being insecure.
#include <ctype.h> // isalpha() returns true if the value is a letter
#include <stdlib.h> // EXIT_SUCCESS
#include <stdio.h> // puts(), printf(), scanf()
int main(void)
{
for(;;) { // for-ever ... endless loop since the user exits by answering
// 'n' or 'N' two times
puts("Would you like to convert a number today?\nPlease press Y or N:");
char input;
if (scanf(" %c", &input) != 1) // We reached EOF ... end of file
break; // that's improbable for stdin,
// but input could be redirected to
// read from a file instead.
if (input == 'y' || input == 'Y') {
puts("\nThank you!\nWhat number?");
int number;
scanf("%d", &number);
if (isalpha((char unsigned)number)) // *)
printf("\nYour Number \t ASCII letter\n%d\t %c\n\n", number, number);
else
puts("Sorry, but that's not the ASCII code of a letter :(\n");
}
else if (input == 'n' || input == 'N') {
puts("\nWould you like to convert a letter instead?\nPlease press Y or N:");
scanf(" %c", &input);
if (input == 'y' || input == 'Y') {
puts("\nGreat choice adventurer!\nWhat letter will it be today?");
char letter;
scanf(" %c", &letter);
if (isalpha(letter))
printf("\nYour letter \t ASCII code\n%d\t %c\n\n", letter, letter);
else
puts("Sorry, but that's not a letter :(\n");
}
else if (input == 'n' || input == 'N') {
puts("\nDifficult to please, I see...\n\nI suggest you move on with that attitude!\n");
puts("Bye bye then.");
return EXIT_SUCCESS;
}
}
else {
puts("Sorry I did not recognize your command... Please retry.");
puts("Press Y or N next time!\n");
}
}
}
*) isalpha() (and the other functions in <ctype.h>) expects a value that fits in a unsigned char or the value EOF. It has undefined behaviour for other values. Since we read user input into an int we cannot be sure that's the case so we have to cast the value to unsigned char before passing it to isalpha() (and friends).
Next time you ask a question please include your full code, including variable declarations, functions like test() and conversion() and #includes. But please, post an example that focuses on your problem at hand. All that dialog you included would not have been necessary.

Program looping two times (printing statement twice)

I'm trying to make a simple program for which the user is supposed to enter character 'a'. It is supposed to loop until 'a' is input. I have one statement printed if there is no input which works correctly. There is another statement if an incorrect letter or number is input, but the problem is that this causes the program to loop more than once and it prints the statements multiple times. Any help in fixing this is appreciated.
#include <stdio.h>
int main()
{
char input;
int i, len,num;
len = 1;
do
{
puts("Please enter alphabet 'a': ");
scanf("%c", &input);
for(i=0; i<len; i++)
{
if(isalpha(input)==0)
{
printf("Please input something.\n");
continue;
}
if(input == 'A' || input == 'a')
{
printf("Congratulations! You successfully input letter 'a'.");
return(0);
}
else
{
printf("That's not letter 'a'.");
}
}
}
while(1);
}
The problem is that after entering the character, you press newline and this is send to the input buffer. Now the next time scanf() is called, it reads the value from the buffer which is '\n' and scanf() thus stores this to input. Now this can be easily solved by the method pointed by #Gopi, but there is a better way. This is the code.
#include <stdio.h>
#include<ctype.h>
int main()
{
char input,ch;
do
{
puts("Please enter alphabet 'a': ");
scanf("%c", &input);
while( input!='\n' && (ch=getchar())!='\n' && ch!= EOF); // look here
if(isalpha(input)==0)
{
printf("Please input something.\n");
continue;
}
if(input == 'A' || input == 'a')
{
printf("Congratulations! You successfully input letter 'a'.");
return(0);
}
else
{
printf("That's not letter 'a'.");
}
}
while(1);
}
Now with the statement while((ch=getchar())!='\n' && ch!= EOF);, all the characters like '\n' are just flushed and not stored to input and thus solves the problem.
Also note that you don't need the for loop here, its useless for this code ( unless this is not your original code and there are other parts in it ).
There is a newline character in the buffer after the first input which is not flushed and that is being picked up by the %c in the second iteration.
Change your scanf() to
scanf(" %c", &input);
Note the space before %c which gobbles the newline character

scanf char variable in between scanf integer variable doesn't work? [duplicate]

This question already has answers here:
Scanf skips every other while loop in C
(10 answers)
Closed 6 years ago.
I thought of making a calculator, just a simple one with loops and the basic operations, but the weird thing is that the scanf of character in between my scanf for number is being ignored. It works fine if I put it on top of the scanf of integer but it wouldn't look anything like a calculator. Is there any way to solve this issue? It's not yet finished; got an error up to here, so wondering what's wrong.
#include <stdio.h>
#include <stdlib.h>
int main(){
int number1,number2,total;
char a;
printf("This is your personal calculator:(End with ""="")\n");
scanf("%d",&number1);
scanf("%c",&a);
scanf("%d",&number2);
if (a == 'x' || a == 'X' || a == '*'){
total=number1*number2;
printf("%d",total);
} else if (a == '/'){
total=number1/number2;
printf("%d",total);
} else if (a == '+'){
total=number1+number2;
printf("%d",total);
} else if (a == '-'){
total=number1-number2;
printf("%d",total);
} else {
printf("error");
}
system("pause");
return 0;
}
You should test that you get a value from scanf(), every time.
The %c character reads the blank or newline after the first number; use " %c" with a leading space to skip over optional white space before reading the character.
if (scanf("%d", &number1) == 1 &&
scanf(" %c", &a) == 1 &&
scanf("%d", &number2) == 1)
{
...process possibly valid input...
}
else
{
...diagnostics...
}
It will probably be easier to give good diagnostics if you read whole lines with fgets() and parse them with sscanf().
Recommendation 1: show an example of what you type as input and what you get as output. This makes it easier for people to help you (they can tell whether the program is producing the same output for them).
Recommendation 2: echo your input so you can see what the program got. This allows you to tell whether the program got the input you expected. You'd probably find that number2 was not containing what you expected, for example.
Recommendation 3: initialize number1 and number2 to -1 so you can see when the scanf() failed (since you aren't yet checking whether scanf() succeeded).
The problem is because of the newline char \n left over by the scanf. This could be avoided by placing a space before format specifier %c.
Try this
scanf(" %c", &a);
^ An space
this will help you to eat up \n char left over by first scanf
int main()
{
int number1,number2,total;
char a;
printf("This is your personal calculator:(End with ""="")\n");
scanf("%d",&number1);
fflush(stdin); // SIMPLE WAY FLUSH THE INPUT STREAM, INPUT BUFFER IS USUALLY CLEARED.
scanf("%c",&a);
scanf("%d",&number2);
if (a == 'x' || a == 'X' || a == '*'){
total=number1*number2;
printf("%d",total);
} else if (a == '/'){
total=number1/number2;
printf("%d",total);
} else if (a == '+'){
total=number1+number2;
printf("%d",total);
} else if (a == '-'){
total=number1-number2;
printf("%d",total);
} else {
printf("error");
}
system("pause");
return 0;
}

Resources