Program in C not calculating % and break/exit on specific input - c

I'm trying to make a small program, where user enters a list of numbers and at the end it shows how much in % of the numbers are odd or even.
If the user enters no value (just presses enter) it stops request a number and shows the calculation, but if the user enters exit it exits. Additionally I want to check if the entered number is a whole number.
Here what I got so far:
#include <stdio.h>
int main(void)
{
int input, all [100], even[100], odd[100], even_counter, even_print, odd_counter, odd_print, total_counter, total_print, even_p, odd_p;
char cinput;
for (;;)
{
printf("Enter a number: ");
if (scanf("%d", &cinput) != 1) break;
input=(int)(cinput-0);
all[total_counter]=input; //Insert number in all numbers array
if (input % 2 == 0)
{
even[even_counter]=input; //Insert number in even numbers array
even_counter++;
total_counter++;
}
if (input % 2 != 0)
{
odd[odd_counter]=input; //Insert number in odd numbers array
odd_counter++;
total_counter++;
}
}
printf("\n You entered the following numbers: ");
for (total_print=0; total_print<total_counter; total_print++)
{
printf("%d ", all[total_print]); //Show all entered numbers
}
printf("\n Even numbers are: ");
for (even_print=0; even_print<even_counter; even_print++)
{
printf("%d ", even[even_print]); //Show even numbers only
}
printf("\n Odd numbers are: ");
for (odd_print=0; odd_print<odd_counter; odd_print++)
{
printf("%d ", odd[odd_print]); //show odd numbers only
}
printf("\n\n Total numbers entered: %d", total_counter); //Show count of all numbers
printf("\n Even numbers entered: %d", even_counter); //Show count of even numbers
printf("\n Odd numbers entered: %d", odd_counter); //Show count of odd numbers
even_p=(even_counter/total_counter)*100; //Calculate % of even numbers
odd_p=(odd_counter/total_counter)*100; //Calculate % of odd numbers
printf("\n\n Even numbers are %d %% of total number (%d out of %d)", even_p, even_counter, total_counter);
printf("\n Odd numbers are %d %% of total number (%d out of %d)", odd_p, odd_counter, total_counter);
}
What works:
It saves all entered numbers in one array, even and odd numbers in
separate arrays.
It counts how many numbers were entered, how many are even and how
many are odd.
As soon as a non-numeric character is entered it goes to showing the
result.
What doesn't work:
The % calculation always says that it's 0%.
The first number in the odd array is 0.
What I can't figure out:
How to make it go to the results if nothing is entered? Tried
if (scanf("%d", &cinput) != "\n") break;, but it just
got stuck in the loop request another number.
How to make the program exit if exit is entered?
How to check if a whole number is entered?
EDIT
Counters initialized. scanf("%d", &cinput) changed to scanf("%d", &input). Changed even_p and odd_p to float (from int). Now the calculation is working fine and the first value in odd_array is good to.
#include <stdio.h>
int main(void)
{
int input, all [100], even[100], odd[100], even_counter, even_print, odd_counter, odd_print, total_counter, total_print;
even_counter=0;
even_print=0;
odd_counter=0;
odd_print=0;
total_counter=0;
total_print=0;
for (;;)
{
printf("Enter a number: ");
if (scanf("%d", &input) != 1) break;
all[total_counter]=input; //Insert number in all numbers array
if (input % 2 == 0)
{
even[even_counter]=input; //Insert number in even numbers array
even_counter++;
total_counter++;
}
if (input % 2 != 0)
{
odd[odd_counter]=input; //Insert number in odd numbers array
odd_counter++;
total_counter++;
}
}
printf("\n You entered the following numbers: ");
for (total_print=0; total_print<total_counter; total_print++)
{
printf("%d ", all[total_print]); //Show all entered numbers
}
printf("\n Even numbers are: ");
for (even_print=0; even_print<even_counter; even_print++)
{
printf("%d ", even[even_print]); //Show even numbers only
}
printf("\n Odd numbers are: ");
for (odd_print=0; odd_print<odd_counter; odd_print++)
{
printf("%d ", odd[odd_print]); //show odd numbers only
}
printf("\n\n Total numbers entered: %d", total_counter); //Show count of all numbers
printf("\n Even numbers entered: %d", even_counter); //Show count of even numbers
printf("\n Odd numbers entered: %d", odd_counter); //Show count of odd numbers
float even_p=((float)(even_counter)/total_counter)*100; //Calculate % of even numbers
float odd_p=((float)(odd_counter)/total_counter)*100; //Calculate % of odd numbers
printf("\n\n Even numbers are %f %% of total number (%d out of %d)", even_p, even_counter, total_counter);
printf("\n Odd numbers are %f %% of total number (%d out of %d)", odd_p, odd_counter, total_counter);
}
Now I just need the input to be checked if it's a whole number (display a message, but continue to ask for numbers), go to calculation if no value is entered, quit if exit is entered. And I forgot - the user should not be able to go to calculation if he enters less than 10 numbers. :(

even_p=(even_counter/total_counter)*100;
The above preforms integer division. You don't get an exact divisor, but the the integer immediately preceding it. Since even_counter is always less than total_counter you get zero.
A simple fix is to multiply first, and divide second:
even_p = even_counter * 100 / total_counter;
But your program has undefined behavior all around regardless. You don't initialize all of your variables. For instance, odd_counter isn't initialized, and yet you confidently read its value here:
if (input % 2 != 0)
{
odd[odd_counter]=input; //Insert number in odd numbers array
odd_counter++;
total_counter++;
}
The things you can't figure out can fill a post on their own. It's all about parsing. You need to read an entire line (say with fgets) and then try to parse it (for instance, with repeated applications of sscanf).

There are several issues in the code.
First, your variables, especially odd_counter and so on are not initialised. Hence, an expression like odd[odd_counter]=input yields undefined behaviour (and actually you have a good chance that the program crashes). Note that in C local variables of integral type are NOT by default initialized, neither with 0 nor with any other value. So you need to write int odd_counter=0, even_counter=0, ... and so on. Otherwise your program might yield a correct output (as a correct output is one of thousands of possible outputs due to undefined behaviour), but it is for sure not guaranteed.
Second, even_p=(even_counter/total_counter)*100 performs an integer division (nothing behind the comma), so even_counter/total_counter will always be 0 if total_counter is greater than even_counter. So you could write even_p=((even_counter*100)/total_counter), or (((float)even_counter)/total_counter)*100. Decide if even_p should be float or double as well.
Third, you use %d (i.e. int) to scan into a variable of type signed char. Use scanf("%hhd", &cinput) instead; Format specifier %d together with length sub-specifier hh tells scanf to scan a numerical value into a signed char target (confer printf/scanf reference). Or: change type of variable cinput to int.
After fixing all these issues, the topic "Why is the first value in odd_array always a 0" should be solved as well.

You declare
char cinput;
and then use it in
scanf("%d", &cinput)
That's bad, very bad... Format specifier "%d" expects a pointer to int as a corresponding parameter, not a pointer to char. And int is longer than char (typically 4 vs. 1 byte), so the input value gets stored outside the destination cinput variable.
What happens next is Undefined Behavior.

Related

Finding sum of 2 variables from 1 statement in C

I recently started learning C and must create program that scanf two integer values from standard input separated by a space then printf the sum of these two integers. Must be able to accept negative values. I'm using repl.it to write code 1st then pasting in .c to compile.
Attempt:
#include <stdio.h>
int main(void) {
int j = 0;
printf("Enter 2 integers separated by space and press enter:\n");
while (scanf("%d", &j) == 1) {
printf("Here is the sum:"%d", j);
}
return 0;
}
Except this prints
Here is the sum: 1Here is the sum: 2
The output is wrong so what mistake did I make? Whats the correct method to get expected values?
(eg 1+2=3)
Your code is incorrect. It does not even compile due to "Here is the sum:"%d" ill formatted string. The program will repetitively scan an integer from standard input and print it as it was result of a sum.
Parsing two integers separated by a space can be easily done with scanf() function by using "%d %d" pattern. The function scanf() returns a number of successfully parsed arguments thus value of 2 is expected on correct input. Finally, add both number and print the result.
#include <stdio.h>
int main(void) {
int i, j;
if (scanf("%d %d", &i, &j) == 2) {
printf("Here is the sum: %d\n", i + j);
return 0;
}

Stop Decimal Values From Being Entered into C Program

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

what is the problem with my code, it is not returning value if b!=-1

what is the problem with my code, it is not returning value if b!=-1
#include <stdio.h>
int find_even(int k){
int a,b,i=0;
scanf("%d",&a);
while (a>=0){
if(i<k){
if (a>=0 && a%2 == 0){
b=a;
i++;
}
}
scanf("%d",&a);
}
if (i<k){
b=-1;
}
return b;
}
void main(){
int k;
printf("Enter the value of K : ");
scanf("%d",&k);
printf("Enter the sequence of non negative integers and at end enter a negative integer : ");
if (find_even(k)<0)
printf("No %dth even integer exist.",k);
else
printf("Result = %d. ",find_even(k));
}
I am trying to get the kth even digit but I am not getting any value returned whenever the value of b isn't equal to -1
The reason you do not seem to get output unless you enter -1 is because you must enter at least k even numbers for (i<k) to be true. Each time you enter a positive even number in the loop, i increments:
if (a>=0 && a%2 == 0){
b=a;
i++; // here
So if you enter a positive even number (say 2) more than k times, you will get a result that isn't -1.
After you return from the function, if the result is negative, you do:
printf("No %dth even integer exist.",k);
If the result is positive, you go back into the function for a second time:
printf("Result = %d. ",find_even(k)); // This is going to re-enter find_even
I think what you want to here is save the result of the function call and act on that. Like this:
int result = find_even(k);
if (result<0)
printf("No %dth even integer exist.",k);
else
printf("Result = %d. ", result);
Edit: I think I understand what you are trying to do now. It was a bit confusing given the request and the way things line up on the screen. Add a \n to the end of the printf to make this less confusing on the terminal:
printf("Enter the sequence of non negative integers and at end enter a negative integer :\n");
Now, all the input will be aligned and make more sense.
Also, be careful with scanf() as it is not the most reliable function. It is good for tinkering, but it is unsafe for general purpose use. Check out this little guide for more info on scanf and all of its intricacies to using it correctly.

Validating input with isdigit for a factorial program

I wrote the following code in C to make a program which calculate the factorial of any number.
I want to add to my program some validation/error handling, such as preventing random characters, floats or negative values from being entered, so I used the isdigit function.
Unfortunately there is a hidden problem which I don't know how to solve. When I enter any input it considers it to be false (i.e. not a digit) even if it's a positive digit.
#include <stdio.h>
#include <ctype.h>
int main()
{
char choice;
unsigned long long int factorial=1;
int counter,number;
for(;;)
{
printf("Please , enter a positive integer number only : ");
scanf("%d",&number);
fflush(stdin);
if(isdigit(number))
{
for(counter=number;counter>1;counter--)
factorial*=counter;
printf("The factorial of number %d is %llu",number,factorial);
}
else
{
printf("\a\aError\n");
continue;
}
printf("\n1-Press c or C if you want to calculate the factorial of a new number\n2-Press any key if you want to exit the program\n ");
scanf("%c",&choice);
if(choice=='c'||choice=='C')
{
factorial=1;
system("cls");
continue;
}
else
return 0;
}
}
You are using isdigit wrong. Read its documentation to find out what it actually does.
You probably meant:
if ( number >= 0 && number <= 9 )
However you also need to check whether scanf succeeded or not. If they type in some words, then scanf("%d" fails and does not update number, so trying to access number in that case accesses an uninitialized variable. To deal with that you could either check the return value of scanf, or do:
int number = -1;
scanf("%d",&number);
because the value will be left unchanged if the input failed.
NB. Don't use fflush(stdin)
isdigit checks a single character if that's a decimal digit character.
But, your input could be say 25, multiple characters. So, I changed a portion:L
char input[30];
for(;;)
{
printf("Please , enter a positive integer number only : ");
scanf("%s",input);
if(isdigit(input[0]))
{
number = atoi(input);
for(counter=number;counter>1;counter--)
Keeping rest of your program snippet same.
Here, isdigit is used to check if the first character in input is a digit and therefore a valid candidate to be converted by atoi into an integer value number.

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