Why does this while-loop in C not work? - c

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.

Related

I am having problem using scan function in 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

Enter the value of two number

Actually, I'm learning C langage and I have written a programm
Enter the value of 2 numbers as shown below.
#include<stdio.h>
int main()
{
int a, b, c;
printf("Enter two numbers to add\n");
scanf("%d%d", &a, &b);
printf("Sum of the numbers = %d\n", c);
return 0;
}
But if I enter an alphabet I'm getting some 1522222 numbers. Instead of
this I want it throws an error as invalid input if I type alphabet ie a,b,c.
How could I do that?
You can check the return value of scanf. If it is successful, it should return 2, since you're reading two values. If you get anything else, you know that the input is incorrect. Try this:
if (scanf("%d%d", &a, &b) != 2)
printf("Invalid input type!\n");
else
printf("Sum of the numbers = %d\n", a+b);
On a different note, you don't initialize c anywhere, so printing it is undefined behavior. You don't even need c for this, you can just print a+b instead.

program to detect whether only integer has been given or not goes into infinite loop

// program to detect whether only integer has been given or not
int main() {
int a, b, s;
printf("Enter two proper number\n");
BEGIN:
s = scanf("%d %d", &a, &b); //storing the scanf return value in s
if (s != 2) {
printf("enter proper value\n");
goto BEGIN;
}
printf("The values are %d and %d ", a, b);
}
This program to detect whether only integer has been given or not goes into infinite loop when invalid data is entered instead of asking for new values
why doesn't the goto work here?
Note that when scanf gets bad input (for example you enter cat dog) that input remains in the input buffer until you take steps to clear it out. So the loop keeps repeating and rejecting the same input which is still there.
It is simpler to use fgets and sscanf and if the scan fails, you just forget the input string and get another.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a, b;
char str[42];
do {
printf("Enter 2 numeric values\n");
if(fgets(str, sizeof str, stdin) == NULL) {
exit(1);
}
} while(sscanf(str, "%d%d", &a, &b) != 2);
printf("Numbers are %d and %d\n", a, b);
}
Program session:
Enter 2 numeric values
cat dog
Enter 2 numeric values
cat 43
Enter 2 numeric values
42 dog
Enter 2 numeric values
42 43
Numbers are 42 and 43
Note that goto is poor practice in C and should be used only where there is no other way of constructing the code — which there usually is.
There are multiple reasons scanf() can return a value different from 2:
there is pending input that cannot be converted according to the conversion specification. For example if there is an A pending in the input stream, the %d conversion fails and the A stays in the input stream. Your code just keeps trying this conversion and will never stop. You should read and discard the offending input before re-trying.
the input stream has had a read error or hit the end of file. If at least one conversion succeeded, the number of successful conversions is returned, otherwise EOF is returned. If EOF is returned, there is no point trying again since no more input will be available.
Note also that it is considered bad style to use goto for constructions that are better expressed with flow control statements such as while and for.
Here is a corrected version:
#include <stdio.h>
// program to detect whether only integer has been given or not
int main() {
int a, b, s, c;
printf("Enter two proper numbers: ");
for (;;) {
s = scanf("%d%d", &a, &b); //storing the scanf return value in s
if (s == 2) // conversions successful
break;
if (s == EOF) {
printf("unexpected end of file\n");
return 1;
}
/* discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("Invalid input. Try again: ");
}
printf("The values are %d and %d\n", a, b);
return 0;
}
scanf returns the number of characters. As a result, s will be equal to the number of characters you have written is 2, then your loop will stop. The reason this runs infinitely many times is that the number of characters you have entered differed from 2. Print s to see what value it holds and you will get more information.

How to read an unknown quantity of integers from console?

I have entries like these:
0 5 260
1 0 -598
1 5 1508
2 1 -1170
I don't know previously how many (console) inputs I'll get, so I have to read until there are no entries left.
I started with a code like this:
int a, b, c;
while(scanf("%d %d %d", &a, &b, &c)!=EOF){
// do stuff here
}
But it never stops asking for new input.
Then, I saw people in other threads suggesting this:
int a, b, c;
while(scanf("%d %d %d", &a, &b, &c)==1){
// do stuff here
}
In this case, it doesn't even enter the while.
Does anyone know what I'm doing wrong?
An approach: Continue asking for input until the input is closed (EOF) or some problem is encountered. (Invalid line of input)
The below uses fgets() to read a line.
Then, " %n" to detect where scanning stopped. If scanning does not reach %n, n will still have the value of 0. Otherwise it gets the offset in buffer where scanning stopped, hopefully it was at the null character '\0'.
char buffer[100];
while (fgets(buffer, sizeof buffer, stdin)) {
int n = 0;
sscanf(buffer, "%d%d%d %n", &a, &b, &c, &n);
if (n == 0) {
fprintf(stderr, "3 int were not entered\n");
break;
}
if (buffer[n] != 0) {
fprintf(stderr, "Extra input detected.\n");
break;
}
// do stuff here with a,b,c
}
There are many approaches to solve this issue.
while(scanf("%d %d %d", &a, &b, &c)==1)
means that "if scanf() successfully read just one value, proceed in the loop."
Therefore, if you enter something like 0 junk, the scanf() read just 1 data and will enter the loop once.
Try using
while(scanf("%d %d %d", &a, &b, &c)==3)
to have it enter the loop when scanf() successfully read three values, which is what expected.

Why my program combines two printf commands?

So here is my program. It is suposed to write out square of some intiger.
#include <stdio.h>
int main (){
int a;
printf("Type an intiger.");
scanf("%i", &a);
printf("Square of that intiger is %i", a*a);
return 0;
}
When i run a program in Eclipse it first requires me to input a number.I put in 5. And then as output it gives me
Type an intiger.Square of that intiger is 25.
It should first print "Type an intiger" and then the rest. But it just combines two printf commands. What is the problem?
You need a newline character - printf("Type an intiger.\n");
In computing, a newline, also known as a line break or end-of-line
(EOL) marker, or simply break, is a special character or sequence of
characters signifying the end of a line of text.
Also format specifier for integer is %d
scanf("%d", &a);
printf("Square of that intiger is %d", a*a);
If you want it on separate lines you can always add '\n' to the string to get a new line.
#include <stdio.h>
int main (){
int a;
printf("Type an intiger.\n");
scanf("%i", &a);
printf("Square of that intiger is %i", a*a);
return 0;
}
There is 2 problem in it. First, if you input the integer, it should be %d. Example :
scanf("%d", &a);
The second, after the input, you should print \n. So, it will be like this printf("\n");. Take a look at my code :
#include <stdio.h>
int main (){
int a;
printf("Type an intiger.");
scanf("%d", &a);
printf("\nSquare of that intiger is %d", a*a);
return 0;
}
In code::blocks it compiles fine anyway put a \n at the end of the first printf and change %i with %d

Resources