Stop Decimal Values From Being Entered into C Program - c

I have a program which takes input from the user and tells the user which number is bigger num1 or num2. My problem is that i don't want to allow the user to enter a decimal number such as 1.2 etc.
Here is my program so far:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int num1;
int num2;
printf("enter a number: ");
scanf("%d", &num1);
printf("enter another number: ");
scanf("%d", &num2);
printf("\n");
printf("\n");
if (num1 < 0) {
printf("Enter a value which is not below 0!");
}
else if (num1 == num2) {
printf("%d and %d are equal", num1, num2);
}
else if (num1 > num2) {
printf("%d is bigger than %d", num1, num2);
}
else if (num2 > num1) {
printf("%d is bigger than %d", num2, num1);
}
return 0;
}
Currently my program displays an error message if a user enters a negative number.
But I want to deter and stop any decimal numbers from being entered at all weather below 0 as a negative number or not.

You cannot, with standard Console input, prevent the user from entering arbitrary strings. (That would require to receive every single character as it is typed, and suppress "illegal" characters, which is both system specific). So you are stuck with receiving a stream of input and checking its contents. If the input was wrong, you can prompt the user to try again.
There are two basic ways:
You do read floating point numbers with %f. This format skips any whitespace, then tries to parse a number from the following word, and stops when it encounters a character which does not let it continue parsing a number. (That is typically another whitespace separating it from the next number but could be a letter or any other non-numerical character.) Then you check whether it is a whole number. The easiest way to do that is to cut the fraction part of the parsed value and see whether it is equal to the parsed float. An easy way to cut off any decimal places is to truncate it to int: if((int)f != f) { /* user entered a number with decimal places */ }.
You read a word from the input as a string (%s) and parse it manually. That's more complicated but actually a pretty neat beginner exercise, in particular if you try to come up with all possible stupid inputs (unprintable characters, very long words, several minus sings etc.) and test and harden your routine against them.
One important advice: Whatever way you decide to go, make sure to evaluate the return value of the input routine. I see that you do not evaluate the return value of scanf in your program, but that is essential. scanf returns the number of successfully converted items (i.e. in your case 1 if a number could be read). If scanf returns 0, it could not parse a number from the input (for example because the first character in the input is a decimal point which cannot be part of an integer number), and you have to perform some kind of error handling. In particular, you must read away the offending word (or line? Depends on the strictness you want to impose on the input format) of the input.
Another advice on the side is to prepare your program for non-interactive use. This means that there is nobody sitting in front of a console entering numbers and hitting enter — instead the standard input comes from a file or another program. In order to provide input from a file one would write myprog < sometextfile.txt in a Console on Windows as well as in a Linux etc. terminal. Programs profit enormously from being "scriptable"; it also makes it easy to quickly test them against many kinds of input in a repeatable fashion. But if the input comes potentially from a file there is, for example, no need to expect every number (or every pair of numbers) to be on its own line.

1.2 is not a decimal data type. It is a float data type!
As you've used %d in the scanf, the value before . will get stored in num1 and 0 will be stored in num2;
int num1,num2;
scanf("%d%d",&num1,&num2);
printf("%d %d",num1,num2);
if entered 1.2 & 3.4
o/p:- 1 0
if entered 1 & 3.4
o/p:- 1 & 3

Try this concept - 'Scanset' or 'Negated Scanset'
scanf("%[^.]", &num1); // does not allow decimal point (.) and will accept not only number but all other characters
or
scanf("%[0-9]", &num1); // only accept positive integer

Related

Having Difficulty with isdigit() in C

I have been trying to add some experience in C to my experience with Python and started with a basic addition program. One thing that I'm trying to do is check if the input is a number or a character as seen here:
#include <stdio.h>
#include <ctype.h>
int main()
{
int n, sum=0,c,value;
printf("Enter the Number of Integers You Want to Add\n");
scanf("%d", &n);
if(isdigit(n))
{
printf("Enter %d Integers\n", n);
for(c=1; c<=n; c++)
{
scanf("%d", &value);
if(isalpha(value))
{
printf("ENTER INTEGER NOT CHARACTER\n");
break;
}
else
{
sum = sum + value;
}
}
printf("Sum of Entered Integers = %d\n",sum);
}
else
{
printf("ENTER INTEGER NOT CHARACTER\n");
break;
}
return 0;
}
Initially I had tried this using isalpha(), and the program worked fine when adding numbers but interpreted characters as zeros instead of printing the "not an integer" statement. However, now that I reworked it to use isdigit(), it does not recognize ANY input as an integer, whether or not it is. Is there something that I'm just doing wrong?
When you use scanf to read an integer, you get just that, an integer. (To read a single character, you need %c and a pointer-to-char).
When you use isdigit(), you need to supply the representation of that character (e.g. in ASCII, the character '0' has the representation 48, which is indeed its value as an integer). To recap:
isdigit(0) is false
isdigit(48) is true (for ASCII, ISO8859, UTF-8)
isdigit('0') is true (no matter the character set)
isdigit('0' + n) is true for integers n = 0 ... 9
PS: Not testing the return value from scanf is asking for trouble...
Neither isdigit nor isalpha work as you think they do. The intent of those library functions is to check whether a given code point, represented as an int, is within a subset of points defined by the standard to be digit characters or alpha characters.
You should be checking the results of your scanf calls rather than assuming they just work, and acting on those results accordingly. If you request an integer and one is successfully scanned, then it will tell you so. If that fails, your course of action is probably to consume the rest of the line (through newline or EOF) and possibly try again:
#include <stdio.h>
int main()
{
int n,value,sum=0;
printf("Enter the Number of Integers You Want to Add\n");
if (scanf("%d", &n) == 1 && n > 0)
{
printf("Enter %d Integers\n", n);
while (n--)
{
if (scanf("%d", &value) == 1)
{
sum = sum + value;
}
else
{
// consume the rest of the line. if not EOF, we
// loop around and try again, otherwise break.
while ((value = fgetc(stdin)) != EOF && value != '\n');
if (value == EOF)
break;
++n;
}
}
printf("Sum of Entered Integers = %d\n", sum);
}
return 0;
}
Properly done you should be able to enter valid integers beyond single digits (i.e. values > 10 or < 0), which the above allows.
The %d marker to scanf tells it to interpret the input as a number (more accurately, it indicates that the pointer in the arguments points to an integer type). It can't do anything but put an integer into that argument. If it can't interpret the input as a number, scanf stops scanning the input and returns immediately.
isdigit() evaluates its argument as a character code, as Jens points out above. However, scanf already turned the character code into a pure number.
From the scanf man page:
On success, the function returns the number of items of the argument list
successfully filled.
In your program, you are trying to read just one item from stdin, so scanf should return 1. So check for that and you'll know that it all worked out ok:
printf("Enter the Number of Integers You Want to Add\n");
while(scanf("%d", &n) != 1) {
printf("That's not a valid integer. Please try again.\n");
}
You cannot use isdigit() the way you are using it because you're already using scanf to convert the user input to an integer. If the user had not input an integer, scanf would have already failed.
Look at the man pages for all the C functions you are using, they will show you what the function expects and what the return values will be under different circumstances.
In the case of isdigit(), the input is expected to be an unsigned char representing an ASCII character. This can be a bit confusing because ASCII characters are in fact represented as a type of integer, and a string is an array of those. Unlike languages like Python which hide all that from you. But there is a big difference between the STRING of a number (array of characters that contain the characters of the digits of the number) and the INTEGER itself which is in a form the processor actually uses to do math with... (simplified explanation, but you get the idea).

Why does my program return the first inputted value without the decimal every run?

#include <stdio.h>
int main (void) {
int count, value;
double avg, sum;
count = 0;
sum = 0;
printf("please input how many integers you have \n");
scanf("%d", &count);
for (int i = 0; i < count; i++) {
printf("please input your values \n");
scanf("%d", &value);
sum = sum + value;
}
avg = sum / count;
printf("your average is " "%f", avg);
}
Example: count input is 4. input values is 7.6, 1, 2, 3.
I understand that in the for loop scanf sees 7.6 first, but disregards the decimal point as it is not a valid form of input, and passes it along every subsequent scanf in the loop though they never truly accept an input. This results in the only inputted value as 7, but then the program should continue to divide 7 by 4 to retrieve the "Expected" average, but that is not the case. I end up with 7.000000, which I can't figure out why is happening.
Disregard the fact that I am prompting the user to input integer values even though floating point values were inputted because it is part of my homework assignment. Any hints or references to what I should study would be great
I understand that in the for loop scanf sees 7.6 first, but disregards the decimal point [..]
No. That's a matching failure as the input you enter (7.6) doesn't match the format specifier %d. Hence, scanf() fails. That's why you should always check the return code of all the standard functions. See 7.21.6.2 The fscanf function.
If you want to be able to read floating point values then you should read (change your code) to read floats (or doubles).
For example to read a double:
double value;
if (scanf("%lfd", &value) != 1) {
/* handle failure */
}
A general suggestion: Don't use scanf() if at all possible. Please read Why does everyone say not to use scanf? What should I use instead? for further explanation.
Your reasoning seems to be correct, except for the assumption that scanf will set value to zero on the subsequent iterations. Instead, after reading up to the period on the first iteration and assigning 7 to value, on subsequent iterations scanf will see the period, conclude that the input doesn't match the format, and not touch value at all, leaving it as 7 on every iteration. (It should return 1 on the first iteration and 0 on subsequent ones, to indicate the number of items matched and assigned)
So, the loop will add 7 on every iteration, and then divide by the number of iterations, giving a result of 7.

Finding Mean value program. Variable declaration and inputs

The program always prompts me to give one more input, if I declare 3 vars asks 4 inputs etc... The catch here is that if i put another variable inside the program, it always prompts me to input one more from the number i declared at the first place.
It DOES show the average correctly, but always asks me to give one more input which i think program doesnt even count and probably its the last input it asks me, but its there!
//Variable declaration.
int math,pro,net;
int average;
//ask user to give 3 grades.
printf("Give me your grades from your last semester\n");
//prompt user.
scanf("%d\n %d\n %d\n",&math,&pro,&net);
// simple average.
average = (math+pro+net)/3;
// show average.
printf("Your average is :%d\n\n",average);
change
scanf("%d\n %d\n %d\n",&math,&pro,&net);
to
scanf("%d %d %d",&math,&pro,&net);
however, the real problem was the last newline character in your scanf format. scanf would keep on eating up whitespace character and won't terminate. however, if you send to stdin an EOF sign (hit ctrl+d on linux) the average will be computed with 3 variables specified.
note that newlines are treated by scanf same as other whitespace characters.
Its because extra "\n" at the end of the scanf function. You can either Do the following code:
scanf("%d %d %d",&math,&pro,&net);
or if you want to follow your coding standard then write:
scanf("%d\n %d\n %d",&math,&pro,&net);
Also note that your calculation is in itegers. If your grades are in the continental range (i.e. 1..5) you probably want to float average = (math+pro+net)/3.; printf("Your average is :%f\n\n",average); to avoid the loss of the fractional part od the result.

getchar not working in switch case (c)

Using a very simple calculator program that prompts a user for an operation to perform, followed by a prompt for two integers on which to perform this operation. The program is supposed to loop after these operations, except in the case where the user enters the character 'q', at which point the program is supposed to quit.
#include <stdio.h>
int main (void)
{
char c;
int number[2], num1, num2, result;
double num1d, num2d, resultd;
int done=1;
while(done)
{
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
c = getchar();
printf("\tplease enter a number \n");
scanf("%d",&number[0]);
printf("\tplease enter another number \n");
scanf("%d",&number[1]);
num1 = number[0];
num2 = number[1];
switch(c)
{
case('-'):
result = num1-num2;
printf("\nThe first number you entered subtracted by the second number is %d.\n", result);
break;
case('+'):
result = num1+num2;
printf("The first number you entered added to the second number is %d.\n", result);
break;
case('*'):
result = num1*num2;
printf("The first number you entered multiplied with the second number is %d.\n", result);
break;
case('/'):
num1d = (double) num1;
num2d = (double) num2;
resultd = num1d/num2d;
printf("The first number you entered divided by the second number is %g.\n", resultd);;
break;
case('q'):
printf(" Now Exiting...\n");
done=0;
break;
default:
puts("Invalid key pressed. Press q to exit");
break;
}
}
return 0;
}
Works correctly for a single calculation, but subsequently performs oddly; in particular it prints
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
printf("\tplease enter a number \n");
altogether.
The standard method of clearing the input buffer while (getchar() != '\n'); doesn't fix this. One out of two times that this text displays incorrectly the user can still use the program as if the instructions were displaying as they should (so the user can type an operation such as +, carriage return, and then some integer and a carriage return, and the program will perform correctly from that point on) Every other time however the program will put "Invalid key pressed. Press q to exit" regardless of input.
What everyone else here is saying is true, getchar() returns an int but that's not your problem.
The problem is that getchar() leaves a newline character after you use it. If you're going to use getchar() you must always consume the newline char afterwards. This simple fix:
printf("\t What sort of operation would you like to perform? \n \t Type + - * / accordingly. \n");
c = getchar();
getchar(); //<-- here we do an extra getchar for the \n
printf("\tplease enter a number \n");
scanf("%d",&number[0]);
printf("\tplease enter another number \n");
scanf("%d",&number[1]);
and that will eliminate the problem. Every time you type <somechar><enter> it's really putting two characters on the buffer, for example if I hit + and enter I'm getting:
'+''\n' // [+][\n]
getchar() will only get the first of these, then when getchar() is called again it won't wait for your input it will just take that '\n' and move on to the scanf()
You shouldn't mix character-by-character with more high-level input functions such as scanf(). It's better to use scanf() to input the command character too, but of course then you will have to press enter after the command. I believe this it the root cause of your problems.
As an aside, note that getchar(), despite it's name, returns int, not char. This is because it can return EOF which is a special constant whose value is different from that of all characters.
Further, you should always check the return value of I/O functions like scanf(), they can fail if the input doesn't match the pattern string.
As a debugging hint, you can of course print the value of c before interpreting it, so you can easier see and understand the flow of the program.
I'm guessing it works the first time, but not the next time. This is because the scanf calls leaves the newline in the input buffer so the next time getchar is called in the loop it will return the newline character. Add a space after the format in the scanf calls
scanf("%d ",&number[0]);
and it will discard remaining whitespace from the buffer.
Use a debugger to step through the code and check the variables to verify.
Your getchar should return int. The reason is as below
getchar reads characters from the program's standard input
and returns an int value suitable for storing into a char.
The int value is for one reason only: not only does getchar
return all possible character values, but it also returns an
extra value to indicate that end-of-input has been seen.
The range of a char might not be enough to hold this extra value,
so the int has to be used.
So basically you need to change char c to int c in your code

How to print the smallest number from a set of inputted integer?

I want to write a program where it prompts people to enter a set of integers separated by a space. The user should be able to enter any amount of integer. It will find the two smallest integer in the set and print it out. Printing the smallest number and then printing the second smallest. My question is how do I get the value of min1 to be the first integer they enter, other than a static one? When I did a test run all it printed was a space, why is that? Here is what I have so far:
Update:
I'm now trying this approach, but it just freeze after I enter an input such as 76 5 74 2.
#include <stdio.h>
int min1, min2;
int input;
int main(){
printf("Please enter some integer: ");
scanf("%d", &min1);
while(scanf("%d", &input) != 0){
min1=input;
}
printf("%d", min1);
return 0;
}
You should add \n in the end of the first printf, so it will not buffered.
Also, be care that you work with digits - not integers.
and for your question - just write min1=getchar();.
EDIT: some code that may do what that you want:
printf("Enter numbers. (other chars to end)\n");
int min,input;
scanf("%d",&min);
while (scanf("%d",&input))
if (input<min)
min=input;
printf("min: %d\n",min);
Maybe you need scanf("%d", &number); to read integers.
For your question, just call scanf to read the first number, or set up a flag to indicate if it's the first input.
Why did you got a space printed? Because %c prints characters not numbers, try %d.
But even after that you won't get the answer you are looking for. getchar() gets a character (go figure...) from the user input, and you are storing that character into a numeric value, for single digit numbers it would magically work since even as characters '9' > '8' > '7' > ... > '0', but you'll get the ascii value of the smallest number printed at the end.
You need two things:
Some way for the user to tell your program they are done entering numbers, so some kind of conditional statement
Some way to compare the numbers they have entered so another conditional statement comparing numbers
In sudocode, maybe something like:
while (user still wants to give numbers):
number = get user input
if number does not equal exit_case:
if number < current minimum number:
current minimum number = number
else:
break out of the while loop
print current minimum number
{
int a,b=1,min;
printf("Enter Number\n");
scanf("%d",&min);
while(b<10)
{
scanf("%d",&a);
if(min>a)
{
min=a;
}
b++;
}
printf("Smallest Num ::%d",min);
}

Resources