I am having problem using scan function in C - c

Here if have used two format specifiers in scan function but it only proceeds after taking three numbers though only two numbers are stored.I don't know why is it waiting for the unnecessary 3rd number.
#include <stdio.h>
int main(){
int a ,b ;
printf("Enter values of a and b ");
scanf(" %d %d " , &a ,&b );
printf("a = %d b = %d" ,a ,b);
return 0;
}

why is it waiting for the unnecessary 3rd number.
" %d %d " directs scanf() to wait for some non-white-space after the 2 int to know all trailing white-spaces are consumed.
" %d %d" directs scanf() to return after the 2 int.
The initial space and the second one are actually redundant since %d reads and ignores whitespace before the number, so you can just write:
scanf("%d%d", &a, &b);
but you should also test that scanf() returns 2 indicating 2 successful conversions.
Here is a modified version:
#include <stdio.h>
int main() {
int a, b;
printf("Enter values of a and b: ");
if (scanf("%d%d", &a, &b) == 2) {
printf("a = %d, b = %d\n", a, b);
} else {
printf("invalid input\n");
}
return 0;
}

don't have this issue when I paste the code into this link https://c.runoob.com/compile/11

Related

Passing a non-digit char after an integer to scanf

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n, k;
scanf("%d %d", &n, &k);
printf("%d %d\n", n, k);
return 0;
}
In the above sample code passing to the input
1 2
Would produce an expected output of
1 2
However passing any char in-between these two digits such as
1. 2 or 1 d 3
Will result in a strange output of the following
1 32766
I would like to know why this occurs, as it was to my belief that scanf would skip over any non-digit input.
You should check the return value of scanf, which tells you the number of data that are read into the passed arguments, here it is k.
In your case, the return value will be zero as %d cannot be used to read in a char in C. If the first input is a char it will be 0, 1 if the first value is int and the second value is a char, 2 if both of the values are int.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n, k, rc;
rc = scanf("%d %d", &n, &k);
if (rc != 2)
{
printf("scanf failed to set the values for n and k\n");
}
else
{
printf("valid input for n and k\n");
}
printf("%d %d\n", n, k);
return 0;
}
So the int k is uninitialized and thus it will store some random value as scanf failed to set the value for this variable.
(Too long for a comment.)   The following answers OP's followup question from a comment.
is there anyway to pass over the character that stops the input stream?
scanf may not be the best or easiest way to do that, but it's still possible to do it using the %n format specifier which returns the offset into the original string during parsing. Following is an example, which uses sscanf but can be easily adapted to scanf.
#include <stdio.h>
void read_three_ints(const char *str) {
int a, n1, b, n2, c;
int ret = sscanf(str, "%d %n%d %n%d", &a, &n1, &b, &n2, &c);
switch(ret)
{
case 3:
printf("'%s': a = %d, b = %d, c = %d\n", str, a, b, c);
break;
case 2:
printf("'%s': a = %d, b = %d, error parsing c = `%s`\n", str, a, b, str + n2);
break;
case 1:
printf("'%s': a = %d, error parsing b = `%s`\n", str, a, str + n1);
break;
case 0:
printf("'%s': error parsing a\n", str);
break;
default:
printf("'%s': scanf error %d\n", str, ret);
break;
}
}
int main()
{
read_three_ints("1 2 3");
read_three_ints("1 2 x");
read_three_ints("1, 2 ");
read_three_ints(";1 ");
read_three_ints("");
return 0;
}
Output:
'1 2 3': a = 1, b = 2, c = 3
'1 2 x': a = 1, b = 2, error parsing c = `x`
'1, 2 ': a = 1, error parsing b = `, 2 `
';1 ': error parsing a
'': scanf error -1

Why am i not getting the correct output

I am writing a piece of code to ask for two specific points in the format P0 x y.
If the user types in Q then the program terminates, for some reason I have trouble outputting the user input (P0 x y) into an output. When I try to run the code and type P0 2 3 it says I have chosen points 0 2.00 3.00.
While the desired output is P0 2 3.
#include <stdio.h>
void main() {
float a, b;
char Q, P, input;
printf("");
scanf("%c", &input);
if (input == 'Q') {
printf("quitting program");
return (0);
} else {
scanf("%c" "%f" "%f", &input, &a, &b);
printf("you have chose points: %c %f %f", input, a, b);
}
return (0);
}
Because you use two scanf. First scanf reads P then second scanf read 0 from command line (from stdin). So after second scanf, input = '0'. This is reason why your program prints 0 2.00 3.00
If you want to print out P0 you have to use string, for example the example below:
#include <stdio.h>
int main()
{
float a, b;
char Q, P, input;
char point[3] = {'\0'};
scanf( "%c" , &input);
point[0] = input;
if(input=='Q')
{
printf("quitting program");
return 0;
}
else
{
scanf( "%c" "%f" "%f", &input, &a, &b);
point[1] = input;
printf("you have chose points: %s %f %f",point, a, b);
}
return 0;
}
As the other answer also mentions, when checking for Q in input, the input byte is consumed. The C standard library provides a fix for this specific problem: you can "return" the consumed byte to the input device (keyboard buffer), and later retry reading from input.
The function is ungetc. It requires quite specific syntax (you should "unget" the same value as was just read; also you must use stdin to specify that you are working with keyboard) and only works for one byte, exactly as you need.
Here is your code with my updates and comments.
#include <stdio.h>
int main()
{
float a, b;
char Q; // only used for checking the "quit" condition
char input[10]; // assuming 9 characters + terminating byte is enough
scanf("%c", &Q);
if(Q=='Q')
{
printf("quitting program");
return (0);
}
else
{
ungetc(Q, stdin); // return one byte to the input device
scanf( "%s" "%f" "%f", input, &a, &b); // "%s" read from the input as string now
printf("you have chose points: %s %f %f",input, a, b);
}
return 0;
}

Stuck on multiplication table in C

I'm new to C programming. I was trying to write a program that accepts an integer from user and displays its multiplication table up to 10 multiples.
This is my program:
#include <stdio.h>
int main ()
{
int number;
int count = 1;
int sum;
printf("Enter a number to display its table: ");
scanf(" %i ", &number);
while (count <=10)
{
sum = number * count;
printf("%i x %i = %i\n", number, count, sum);
count += 1;
}
return 0;
}
Compilation successfully completes, but when I execute the output file, nothing happens, the terminal is stuck at nothing, i've to press ctrl+c to get out..
This is due to the spaces used in your scanf command.
If you replace that with
scanf("%i", &number);
you get an instant response.
With your scanf format " %i ", the scanf function will read (and skip) possible leading spaces because of your leading space in the format.
Then it will read the integer.
Then, due to the trailing space, it will read and discard space until it find a non-space input.
Since there's no non-space input afterward, then scanf will block until you give some non-space input.
Solve simply by not having any spaces in the format. Or by entering some extra dummy input (followed by Enter).
The problem resides with the scanf.
Just replace
scanf(" %i ", &number);
with:
scanf("%i", &number);
and it will work.
#include <stdio.h>
int main (){
int number;
int count = 1;
int sum;
printf("Enter a number to display its table: ");
scanf("%d", &number);
while (count <=10){
sum = number * count;
printf("%d * %d = %d\n", number, count, sum);
count += 1;
}
return 0;
}
Note: You can use both %d or %i where %d specifies signed decimal integer while %i specifies integer.
Problem: The problem of your code was using a whitespace before %i.
Wrong:
scanf(" %i ", &number); //Wrong
Right:
scanf("%i", &number); //Right.

Why does this while-loop in C not work?

Ignoring the fact that negative numbers would not work here, why do positive integers create a infinite loop? I tried many combinations, as simple as a = 20 and b = 4, but every single one creates a infinite loop. What am I doing wrong or not seeing here?
#include <stdio.h>
int mdc(int a, int b) {
while (a != b) {
if (a > b)
a = a - b;
else b = b - a;
}
return a;
}
int main() {
int a, b;
printf("Valores mdc: \n");
scanf("%d %d\n", &a, &b);
printf("%d\n", mdc(a,b));
return 0;
}
Not an infinite loop for the given input:-
The thing is you have used \n in the scanf as a result unless you enter some non-whitespace character - it waits for it.
What did the '\n' do?
From standard explaining the why part - C11 N1570 §7.21.6.2¶5
A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. The directive never fails.
How to give input then?
So it will work if you do this:-
>>> 20 4 Enter
<Somenonwhitespace> Enter
Better solution:
Even better suggestion would be to use
scanf("%d%d", &a, &b);
You don't need to specify the space as you did - %d directive skips over the white space characters.
Code wise
if(scanf("%d%d", &a, &b)!=2){
fprintf(stderr,"Error in input\n");
exit(EXIT_FAILURE);
}
If you were to step the code in a debugger you would discover that the while loop is never even entered. It is not a problem of an infinite while-loop. Rather that scanf() never returns.
Change:
scanf("%d %d\n", &a, &b);
to
scanf("%d %d", &a, &b);
The line scanf("%d %d\n", &a, &b); should be scanf("%d %d", &a, &b); no \n.

How to use scanf in for loop

Whenever i try to read input with
for (int i = 1; i <= 10; ++i) {
scanf("(%c, %d, %d, %d)",&charv,&intv1,&intv2,&intv3);
}
I only get to scanf() once. What is the problem ?
Input -> (P, 1, 2, 3)......(P, 2, 3, 12)
Your usage of scanf() is wrong. You have to provide the pointer to the variable to store the value read by scanf(). You need to use it like below
for (int i = 1; i <= 10; ++i) {
scanf("%c, %d, %d, %d",&charVar,&intvar1,&intVar2,&intVar3);
}
EDIT:
Point 1: The supplied format string should exactly match with the input. Otherwise, scanf() will fail. If your input is not of format (<char>, <int>.... , it will fail. Either of missing (, ), , will cause mismatch in the supplied format string with the input and make scanf() to stop scanning. It's strongly recommended to check the return value of scanf() to ensure it's success.
Point 2: To avoid reading the \n stored by previous ENTER<\kbd> key press, you should add a leading space before %c. So, you can use something like
scanf(" %c, %d, %d, %d",&charVar,&intvar1,&intVar2,&intVar3);
^
|
Notice here
scanf("(%c, %d, %d, %d)",&charvar,&intvar1,&intvar2,&intvar3);
should be
scanf(" %c, %d, %d, %d",&charvar,&intvar1,&intvar2,&intvar3);
Note the space before %c which ignores newline if it exists. If your input is not separated by commas
scanf(" %c %d %d %d",&charvar,&intvar1,&intvar2,&intvar3);
Like Sourav Ghosh and Gopi said, scanf will not work properly with this syntax
scanf("(%c, %d, %d, %d)",&char,&int,&int,&int);
It should be
scanf("%c %d %d %d",&char,&int,&int,&int);
But you can read a string first, and then use sscanf.
Try this code:
char ch;
int a, b, c, i;
char teste[256];
for(i=0;i<10;i++){
fgets(teste, 256, stdin);
sscanf(teste, "(%c, %d, %d, %d)", &ch, &a, &b, &c);
printf("%c %d %d %d\n", ch, a, b, c);
}

Resources