Scanf is ignored [duplicate] - c

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
scanf Getting Skipped [duplicate]
(1 answer)
Why is adding a leading space in a scanf format string recommended?
(2 answers)
Closed 1 year ago.
I have an assignment in which I have to input dimensions of the first matrix, then which operation i would like to perform('-', '+' or '*'; subtraction, addition and multiplying respectively), and after that dimensions of the second matrix. But after entering first dimensions, I receive error message related to char. I cannot figure it out, even after reading a lot about whitespaces and errors related to scanf. Please help. Thank you
int main(void){
int rows_1 = 0, columns_1 = 0; //MATRIX_1 DIM
int rows_2 = 0, columns_2 = 0; //MATRIX_2 DIM
char c = ' ';
if(scanf("%d %d", &rows_1, &columns_1)!=2) //input first size
{
fprintf(stderr, "Error!\n");
return 100;
}
scanf("%c", &c);
if( c!='*' || c!='-' || c!='+' ) //error handling for char
{
fprintf(stderr, "Error!\n");
return 100;
}
if(scanf("%d%d", &rows_2, &columns_2)!=2) //input second size
{
fprintf(stderr, "Error!\n");
return 100;
}
return 0;
}

You have two problems:
The first is that c will contain the newline you pressed after the input for rows_1 and columns_1. Add a single leading space in the format string: " %c" to skip leading white-space (like newlines).
The second issue is that the logical condition is wrong and will always be true, no matter the input for c.
You probably want the opposite of c=='*' || c=='-' || c=='+', which according to De Morgan's laws is c!='*' && c!='-' && c!='+' (but you can also use the logical negation operator ! as in !(c=='*' || c=='-' || c=='+')).
This is rather easy to figure out if you think about it for a little. Lets say that c is a newline '\n'. Then c!='*' is true and due to the short-circuit evaluation of the logical operators, the remaining condition will not be evaluated. The same happens for any other character, including the ones you check for (exchange the newline for e.g. '-' and c!='*' will still be true; also try with '*' and then c!='*' will be false but c!='-' will be true).

Related

scanf scans weird question marks in C [duplicate]

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Simple C scanf does not work? [duplicate]
(5 answers)
Closed 4 years ago.
I wrote this code for a school project and I have the following problem.
When I choose 1 at the first time, my program runs fine but as I choose w or r the second time, something goes wrong. None of the 2 ifs is running. I printed usr_ans2 to see the result of scanf and usr_ans2 variable is a weird question mark in a box and not a w or r character as I typed. Also I tried scanf(" %c", usr_ans2) . The question marks do not appear but the if commands are still not running.
int main(){
int usr_ans1;
char usr_ans2;
while(1){
printf("\nSelect action: (1-3)\n");
scanf("%d", &usr_ans1);
if(usr_ans1 == 1){
printf("Select to write or read from a file the text: (w/r) ");
usr_ans2 = scanf("%c", &usr_ans2);
if(usr_ans2 == 'w')
printf("You selected to write");
else if(usr_ans2 == 'r')
printf("You selected to read");
}
else if(usr_ans1 == 2){
printf("Example1");
}
else if(usr_ans1 == 3){
printf("Example2");
}
return 0;
}
scanf() in usr_ans2 = scanf("%c", &usr_ans2); will return 1 (the numbers of successfully converted specifiers) or EOF (some negative value like -1 when end-of-file or error occurs). if(usr_ans2 == 'w') will never be true.
Try
// usr_ans2 = scanf("%c", &usr_ans2);
scanf(" %c", &usr_ans2); // add the space too to skip leading white-space

getc(stdin) does not record '+' and '-' in one variation, however it takes in '*' and '/' [duplicate]

This question already has answers here:
Why reading '+' and '-' not work in Linux?
(3 answers)
Closed 4 years ago.
int main(void) {
char z;
while ( (z = getc(stdin)) != EOF) {
printf("%c", z);
}
int d, flag = 0;
char c;
while ((flag = fscanf(stdin, "%d", &d)) != EOF) {
if (flag == 1) {
printf("%d", d);
} else {
c = getc(stdin);
printf("%c", c);
}
}
return 0;
}
Hi, i have two variations here, there first one is char z which gets the character from input stream and prints it out. it returns exactly what i typed.
The second variation prints out exactly what i type except for the operators '+' and '-'. Kindly enlighten me here. I am confused as multiplication and division works in this variation and not + and -. Below is a screenshot:
The %d format specifier to scanf looks for an integer. Since a + or - preceding some digits is a valid representation of a number, they are read as part of that number.
So when you input 1+2, the 1 gets picked up on the first loop iteration, then +2 gets picked up on the second iteration. When you then print with %d, the leading + is not printed by default.
If you were to input 1-2, you would get the same as output. However instead of reading 1, then -, then 2, it reads 1 then -2. The - still gets printed because it is relevant.
Because +2 is a valid integer, so it is reading all of that in the fscanf(%d), same with -2, which should be a little more obvious.
So fscanf(%d) reads 1, then on the next iteration, happily reads +2 or -2 as an integer.
The + sign is lost in the output since printf() does not print the sign for positive integers by default.

logical or in C programming Language [duplicate]

This question already has answers here:
Why is my c != 'o' || c != 'x' condition always true? [duplicate]
(5 answers)
Closed 6 years ago.
Does anybody have any idea why this always loops for values different than 1 or 0,and also how can i avoid the endless loop in case of giving a character as input?
#include <stdio.h>
int a;
main()
{
do
{
puts("Give 1 or 0 for input:");
scanf("%d",&a);
} while(a!=0 || a!=1);
printf("\n%d",a);
return 0;
}
The only way for the loop to terminate is if both a!=0 and a!=1 are false. Or in other words: it can only end when a == 0 and a == 1 at the same time. That is of course impossible, so the loop never terminates.
If you want to loop to terminate when the user inputs 1 or 0, then you need a logical and operator there:
do
{
puts("Give 1 or 0 for input:");
scanf("%d",&a);
} while(a!=0 && a!=1);
Aside from that, you really must check the return value of scanf, and purge the input stream in case of failure. If you input a character, then scanf will signify it failed, but leave the character in the input stream. The subsequent iterations will just get stuck on trying to read that character.
One way to do so is with scanf itself and the %*s format specifier.
do
{
puts("Give 1 or 0 for input:");
int read_res = scanf(" %d",&a);
if (read_res != 1)
scanf("%*s");
} while(a != 0 && a != 1);
The asterisk in the format string means scanf will still match any non white-space character and purge them from the stream, but will not attempt to assign them into anything (so no extra parameter is required). I also added a leading white-space to %d in order to disregard any leading white-spaces before the number.

Beginning C and I have a bug that is killing me [duplicate]

This question already has answers here:
Problems with C scanf("%c") function to read characters one by one
(4 answers)
Closed 6 years ago.
I am writing some code and I have a prompt in the program driven by a while loop where you make a choice. However, it prints the prompt twice every time it goes through the loop and I just can't figure it out.
while (choice != 'x');
{
printf("\nChoice (a)dd (v)iew e(X)it [ ]\b\b");
scanf("%c",&choice);
if (choice == 'a') add_record();
if (choice == 'v') view_record();
}
The printf line is the one that prints twice. Thanks in advance for any help.
When you enter a character (i.e. type 'a' and press 'Enter'), the newline character ('\n') is also being read in from stdin. You can add a leading space to the format specifier to avoid this:
scanf(" %c", &choice);
The space indicates to scanf to ignore whitespace characters (such as '\n').
There are few things to notice in the question posted.
The outer while loop behavior depends on the variables initialization at first then the values being entered subsequently.
It then manipulates into print the prompt to enter choice, repeatedly (not just twice) depending on how many characters entered as input before 'enter' key is pressed.
The char i/o driver buffers the input entered and each of the characters entered is read by scarf() one at a time in this case, from the buffer. So it is needed to rewrite the code to work as following (expected from my understanding)
char choice = '!', ws = ' ';
int attempts = 0;
while (choice != 'x')
{
printf("\nAttempt:%d Choice (a)dd (v)iew e(X)it [ ]\b\b", ++attempts);
// Eat up the '\n', if one exist and Wait for valid input
while ((scanf("%c", &choice) > 0) && (choice == '\n'));
// Eat up all white space and other chars entered so far, except the last '\n'
while ((scanf("%c", &ws) > 0) && (ws != '\n'));
if (choice == 'a') add_record();
if (choice == 'v') view_record();
}

How to check whether an input string consist of integers

I'm trying to make a while loop where the condition checks that the first four elements of a string are not integers. Here's my code, somehow it doesn't work. I tried using the isdigit function from the ctype.h header.
char tr_code[200];
char *endptr;
scanf("%s", &tr_code);
fd_code=strtol(tr_code,&endptr,10);
while(strlen(tr_code)!=4 && isdigit(tr_code[0])==0 && isdigit(tr_code[1])==0 && isdigit(tr_code[2])==0 && isdigit(tr_code[3])==0)
{
printf("\nInvalid Code. please enter another '4-digit' Code: ");
scanf("%s", &tr_code);
fd_code=strtol(tr_code,&endptr,10);
}
You're using &&, but || is what you should be using:
while(strlen(tr_code) != 4 || !isdigit(tr_code[0]) || !isdigit(tr_code[1]) || !isdigit(tr_code[2]) || !isdigit(tr_code[3]))
With &&, any input that's four characters long, or has a digit in any of the first four positions (even if that memory is leftovers from the last input, since the string could be shorter) will pass.
IIRC 'scanf' signature returns an integer, which is number of characters read at the terminal.

Resources