Basic question about how this C code is working - c

#include <stdio.h>
#include <cs50.h>
int get_pos_int(void);
int main(void) {
int i = get_pos_int();
printf("You entered the positive Integer of %i\n", i);
}
int get_pos_int(void) {
int n;
do {
n = get_int("Insert a positive Integer: ");
}
while(n < 1);
return n;
}
So of course this is just a simple program to test for if a number entered is a number above 0. Out of interest I decided to make this small change to see if it was semantically still correct.
int main(void) {
get_pos_int();
printf("You entered the positive Integer of %i\n", get_pos_int());
}
When running the program with this change, if I input the number '1' it returns me back to the prompt to type an integer, then if I type 1 again it returns 'You entered the positive Integer of 1'
I was just wondering if you could explain what the behaviour is causing this, I like to know why things are working the way they are and it interested me how removing the function being stored in a variable made it behave this way.

Based on your description of what happens, I'm assuming you meant get_pos_int() in your printf.
int i = get_pos_int() stores the return value of the function, not the function itself. So when you made your change, you call the function but discard the value it returns. The function then gets called again in your printf statement. The function being called twice is why you have to enter 1 twice.

Related

Couldn't get rid of multiple outputs in a C program

I couldn't share the original code but the below program is as similar to my problem.
#include<stdio.h>
#include<conio.h>
void clrscr(void);
int reverse_of(int t,int r)
{
int n=t;
r=0;
int count=0;
while (t!=0) /*Loop to check the number of digits*/
{
count++;
t=t/10;
}
if (count==4) /*if it is a 4 digit number then it proceeds*/
{
printf("Your number is: %d \n",n); /*displays the input*/
while (n!=0) /*This loop will reverse the input*/
{
int z=n%10;
r=r*10+z;
n=n/10;
}
return r; /*returns the value to main function*/
}
else /*This will execute when the input is not a 4 digit number */
{
printf("The number you entered is %d digit so please enter a four digit number \n",count);
main();
}
};
int main()
{
int n,r;
void clrscr();
printf("Enter a number: ");
scanf("%d",&n);
//while (n!=0) /*Use this for any number of digits*/
/* {
int z=n%10;
r=r*10+z;
n=n/10;
} */
r=reverse_of(n,r);
printf("The reverse of your number is: %d\n",r);
return 0;
};
This program displays the reverse of a 4 digit number. it works perfect when my first input is a 4 digit number. The output is as below.
(Keep in mind that i dont want this program to display the reverse of
a number unless its 4 digit)
Enter a number: 1234
Your number is: 1234
The reverse of your number is: 4321
Now when i give a non 4 digit number as the first input the program displays that it is not a 4 digit number and asks me for a 4 digit number. Now when i give a 4 digit number as the second input. It returns the correct answer along with another answer which is supposed to be the answer for the first input. (since the program cannot find the reverse value of a non 4 digit number the output always return 0 in that particular case). If i give 5 wrong inputs it displays 5 extra answers. Help me get rid of this.
Below is the output when i give multiple wrong inputs.
Enter a number: 12
The number you entered is 2 digit so please enter a four digit number
Enter a number: 35
The number you entered is 2 digit so please enter a four digit number
Enter a number: 455
The number you entered is 3 digit so please enter a four digit number
Enter a number: 65555
The number you entered is 5 digit so please enter a four digit number
Enter a number: 2354
Your number is: 2354
The reverse of your number is: 4532
The reverse of your number is: 0
The reverse of your number is: 0
The reverse of your number is: 0
The reverse of your number is: 0
Help me remove these extra outputs btw im using visual studio code and mingw compiler.
The problem lies here:
else /*This will execute when the input is not a 4 digit number */
{
printf("The number you entered is %d digit so please enter a four digit number \n",count);
main();
}
You're calling main() from reverse_of().
Try replacing the main(); with return 0; and in main(), do this:
int n,r;
do{
printf("Enter a number: ");
scanf("%d",&n);
r=reverse_of(n,r);
}while(r==0);
printf("The reverse of your number is: %d\n",r);
This happens because of the multiple recursion caused by the call of main() inside of the reverse_of function.
To avoid such thing you can move the printf("The reverse of your number is: %d\n", r); to the inside of the if(count==4){} and your problem is solved!
Also, note that your reverse_of functions does not need to receive the int r, instead it can be written like this:
#include <stdio.h>
int reverse_of(int t)
{
int n = t;
int r = 0;
int count = 0;
while (t != 0) /*Loop to check the number of digits*/
{
count++;
t = t / 10;
}
if (count == 4) /*if it is a 4 digit number then it proceeds*/
{
printf("Your number is: %d \n", n); /*displays the input*/
while (n != 0) /*This loop will reverse the input*/
{
int z = n % 10;
r = r * 10 + z;
n = n / 10;
}
printf("The reverse of your number is: %d\n", r);
return 1;
}
else /*This will execute when the input is not a 4 digit number */
{
printf("The number you entered is %d digit so please enter a four digit number \n", count);
return 0;
}
};
int main()
{
int n, r=0;
while (r!=1){
printf("Enter a number: ");
scanf("%d", &n);
r=reverse_of(n);
}
return 0;
};
Hope it helped!
Well, your program has some ambiguity: If you stop as soon as you get 0, then the reverse of 1300, 130 and 13 will be the same number, '31'.
So, first of all you need two parameters in your function, to deal with the number of digits you are considering, so you don't stop as soon as the input number is zero, but when all digits have been processed. Then you extract digits from the least significant, and add them to the result in the least significant place. This can be done with this routine:
int reverse_digits(int source, int digits, int base)
{
int i, result = 0;
for (i = 0; i < digits; i++) {
int dig = source % base; /* extract the digit from source */
source /= base; /* shift the source to the right one digit */
result *= base; /* shift the result to the left one digit */
result += dig; /* add the digit to the result on the right */
}
return result;
}
The extra parameter base will allow you to operate in any base you can represent the number. Voila!!!! :)
#include <stdio.h>
int main()
{
int src;
while (scanf("%d", &src) == 1) {
printf("%d => %d\n",
src,
reverse_digits(src, 5, 10));
}
}
will provide you a main() to test it.
In contrast to C++, in C, it is allowed to call main recursively. But it is still not recommended. There are only a few situations where it may be meaningful to do this. This is not one of them.
Recursion should only be used if you somehow limit the depth of the recursion, otherwise you risk a stack overflow. In this case, you would probably have to call the function main recursively several thousand times in order for it to become a problem, which would mean that the user would have to enter a value that is not 4 digits several thousand times, in order to make your program crash. Therefore, it is highly unlikely that this will ever become a problem. But it is still bad program design which may bite you some day. For example, if you ever change your program so that it doesn't take input from the user, but instead takes input from a file, and that file provides bad input several thousand times, then this may cause your program to crash.
Therefore, you should not use recursion to solve this problem.
The other answers have solved the problem in the following ways:
This answer solves the problem by making the function reverse_of not return the reversed value, but to instead directly print it to the screen, so that it does not have to be returned. Therefore, the return value of the function reverse_of can be used for the sole purpose of indicating to the calling function whether the function failed due to bad input or not, so that the calling function knows whether the input must be repeated. However, this solution may not be ideal, because normally, you probably want the individual functions to have a clear area of responsibility. To achieve this clear area of responsibility, you may want the function main to handle all the input and output and you may want the function reverse_of to do nothing else than calculate the reverse number (or indicate a failure if that is not possible). The fact that you defined your function reverse_of to return an int indicates that this may be what you originally intended your function to do.
This answer solves the problem by reserving a special return value (in this case 0) of the function reverse_of to indicate that the function failed due to bad input, so that the calling function knows that the input must be repeated. For all other values, the calling function knows that the function reverse_of succeeded. In this case, that solution works, because the value 0 cannot be returned on success, so the calling function can be sure that this value must indicate a failure. Therefore, in your particular case, this is a good solution. However, it is not very flexible, as it relies on the fact that a return value exists that unambiguously indicates a failure (i.e. a value that cannot be returned on success).
A more flexible solution, which keeps a clear area of responsibility among the two functions as stated above, would be for the function reverse_of to not always return a single value, but rather to return up to two values: It will return one value to indicate whether it was successful or not, and if it was successful, it will return a second value, which will be the result (i.e. the reversed value).
However, in C, stricly speaking, functions are only able to return a single value. However, it is possible for the caller to pass the function an additional variable by reference, by passing a pointer to a variable.
In your code, you are declaring your function like this:
int reverse_of(int t,int r)
However, since you are not using the argument r as a function argument, but rather as a normal variable, the declaration is effectively the following:
int reverse_of( int t )
If you change this declaration to
bool reverse_of( int t, int *result )
then the calling function will now receive two pieces of information from the function reverse_of:
The bool return value will indicate whether the function was successful or not.
If the function was successful, then *result will indicate the actual result of the function, i.e. the reversed number.
I believe that this solution is cleaner than trying to pack both pieces of information into one variable.
Note that you must #include <stdbool.h> to be able to use the data type bool.
If you apply this to your code, then your code will look like this:
#include <stdio.h>
#include <stdbool.h>
bool reverse_of( int t, int *result )
{
int n=t;
int r=0;
int count=0;
while (t!=0) /*Loop to check the number of digits*/
{
count++;
t=t/10;
}
if (count==4) /*if it is a 4 digit number then it proceeds*/
{
while (n!=0) /*This loop will reverse the input*/
{
int z=n%10;
r=r*10+z;
n=n/10;
}
*result = r;
return true;
}
else /*This will execute when the input is not a 4 digit number */
{
return false;
}
};
int main()
{
int n, result;
for (;;) //infinite loop
{
//prompt user for input
printf( "Enter a number: " );
//attempt to read number from user
if ( scanf( "%d",&n ) != 1 )
{
printf( "Invalid input!\n" );
//discard remainder of line
while ( getchar() != '\n' )
;
continue;
}
printf( "Your input is: %d\n", n );
//attempt to reverse the digits
if ( reverse_of( n, &result) )
break;
printf( "Reversing digits failed due to wrong number digits!\n" );
}
printf("The reverse of your number is: %d\n", result );
return 0;
};
Although the code is now cleaner in the sense that the area of responsibility of the functions is now clearer, it does have one disadvantage: In your original code, the function reverse_of provided error messages such as:
The number you entered is 5 digit so please enter a four digit number
However, since the function main is now handling all input and output, and it is unaware of the total number of digits that the function reverse_of found, it can only print this less specific error message:
Reversing digits failed due to wrong number digits!
If you really want to provide the same error message in your code, which specifies the number of digits that the user entered, then you could change the behavior of the function reverse_of in such a way that on success, it continues to write the reversed number to the address of result, but on failure, it instead writes the number of digits that the user entered. That way, the function main will be able to specify that number in the error message it generates for the user.
However, this is getting a bit complicated, and I am not sure if it is worth it. Therefore, if you really want main to print the number of digits that the user entered, then you may prefer to not restrict input and output to the function main as I have done in my code, but to keep your code structure as it is.

Keep getting the same answer when writing a recursive function

Note: I'm fairly new to C programming so I don't know everything just yet.
So I'm working on this assignment for my programming class where I have to write a recursive function count_digits( ) that counts all the digits in a string. I wrote the program and got it to compile but when I type in a number, it always gives me the same answer.
This is what my code is:
#include <stdio.h>
int count_digits(int num)
{
static int count=0;
if(num>0)
{
count++;
count_digits(num/10);
}
else
{
return count;
}
}
int main()
{
int number;
int count=0;
printf("Enter any number:");
scanf("%d",&number);
count=count_digits(number);
printf("\nTotal digits in [%d] are: %d\n",number,count);
return 0;
}
Your non void function returns nothing if num is greater than zero. The compiler should warn you about not returning value. The fix:
return count_digits(num/10);
there are a few things to consider:
What happens if you call your function count_digit() more than one time in the program?
What if you enter 0, 10, 100 as number?
Perhaps you should rethink using a static variable here.
Also for debugging, insert some printfs (or use the debugger) in count_digit() to check how your function behaves.

Program returning wrong numbers

I am in an intro coding class and I cannot figure out why this program isn't giving me the correct answer and is instead giving me a seemingly random number.
I have tried just putting it as a constant instead of a scanf and it still gives me issues
#include <stdio.h>
const int MIN_CONST = 7;
int ComputeMinutesLost(int userCigarettes) {
int minLost;
int MIN_CONST;
minLost = userCigarettes * MIN_CONST;
return minLost;
}
int main(void) {
int userCigarettes;
printf("How many cigarettes have you smoked?\n");
scanf("%d", &userCigarettes);
printf("You have lost %d minutes to cigarettes. ", ComputeMinutesLost);
return 0;
}
It should just say how many minutes are lost (cigarettes times 7) but it gives a seemingly random number.
Note: The code you posted probably should have flagged you with compile errors, or warnings. Do you have them turned on?
Change the following:
printf("You have lost %d minutes to cigarettes. ", ComputeMinutesLost);
To:
printf("You have lost %d minutes to cigarettes. ", ComputeMinutesLost(userCigarettes));
^------------^ // forgot to include argument
By the way, the numeric value you are seeing is an integer representation of the address of the function ComputeMinutesLost.
Also, (thanks to #unimportant's comment)
in the following code section: //read the comments...
const int MIN_CONST = 7; // one of these...
int ComputeMinutesLost(int userCigarettes) {
int minLost;
int MIN_CONST; // is not necessary, and masks the other
// remove one or the other
// (as is, this one invokes undefined behavior.)

Variable Buffer?

I have this code which calculates the exponential power of a value, both of which is entered by the user, example, user enters 2^3 = 8, its suppose to work like this but somethings wrong, the end result is 608, when I debug in the pwra function in the counter, even before the counter initiates the result value is set, from where I dont know because I did not set it so the end result is 608. I feel like its a buffer issue but I have tried fflush both in and out, it doesnt work. So when I copy this code to a new window, it works for sometime, then same again, earlier it was showing 624 as the end result.
#include <stdio.h>
int pwra (int, int);
int main()
{
int number, power, xx;
printf("Enter Number: ");
scanf("%i", &number);
printf("Enter Number: ");
scanf("%i", &power);
xx=pwra (number,power);
printf("Result: %i", xx);
return 0;
}
int pwra (int num, int pwr)
{
int count, result;
for(count=1;count<=pwr;count++)
{
result = result*num;
}
return result;
}
Another thing, how can I calculate the exponential value from a float, because when I change all the int to float the end result is always 0.00000 even with %lf.
You're hitting undefined behavior for the below line
result = result*num;
as you've not initialized result. The initial value for an uninitialized automatic local variable is indeterminate. Using that invokes UB.
Always initialize your local variables, like
int count = 0 , result = 0 ; //0 is for illustration, use any value, but do use
Then coming to the case, where you want to change all ints to float, only changing the data type of the variable is not sufficient. You need to change the corresponding format specifiers, too.

An Address is Printed Instead of the Expected Value

I am trying to write a simple program. I am a begineer and i am not getting a value to total. When i am trying to print . I am getting a address as output . Can anyone explain me what is the mistake and correct my program .
#include<stdio.h>
void main()
{
int first,second,total;
printf("enter the value for the first");
scanf("%d",&first);
printf("enter the value for the second");
scanf("%d",&second);
total=power(first,second);
printf("The value for power is %d",power);
}
int power(int doom1,int doom2)
{
int temp=doom1;
int i;
for(i=1;i<=doom2;i++)
{
temp=temp*doom1;
}
return temp;
}
You are printing the wrong variable:
total=power(first,second); //here you are getting return value in variable total
printf("The value for power is %d",power); // power is the function name not variable
Replace this line with:
printf("The value for power is %d",total); // you need to print `total`
Also you have to declare your function prototype before main():
int power(int ,int);
and you should use int main():
int main()
{
// your code
return 0;
}
In addition to passing total to printf instead of power, as you are just starting, make a point to always give your variables an initial value (initialize them). This prevents an attempt to read from uninitialized space which is the bane of new C programmers. (it will save you a lot of headaches). Attempting to read from an uninitialized variable is Undefined Behavior. That can result in anything from slipping by unnoticed, to causing your program to crash. It is to be avoided.
Also, as I explained in the comment, in C, the function main() is type int and it returns a value to its caller (usually the shell, or another program). When using main without arguments, the proper form is:
int main (void)
When accepting arguments, the proper form is:
int main (int argc, char **argv)
In either case, it should return a positive value upon completion. A return 0; at the end is all that is required. exit (0); is another function you can use to return a value. You will also see the form of main with arguments written as:
int main (int argc, char *argv[])
The first and second forms are the practical equivalents of each other, the first recognizing that an array passed to a function in C will decay to a pointer. But for now, just understand that they are equivalent.
You also have an error in your my_power calculation. int temp = doom1; should be int temp = 1; Your calculation was returning a value twice the actual product.
Your style of syntax is up to you, but I would suggest that expanding your syntax a little by using discretionary spaces and lines will make your code much more readable and make finding errors a bit easier. Here is an example regarding all of these points:
#include <stdio.h>
int my_power (int doom1, int doom2);
int main (void)
{
int first = 0; /* Always initialize your variable to prevent */
int second = 0; /* an inadvertant read from an unitialized */
int total = 0; /* value which is Undefined Behavior (bad). */
printf ("\n enter the value for the first : ");
scanf ("%d",&first);
printf (" enter the value for the second: ");
scanf ("%d",&second);
total = my_power (first,second);
printf ("\n The value for my_power is: %d\n\n", total);
return 0;
}
int my_power (int doom1, int doom2)
{
int temp = 1;
int i = 0;
for (i = 1; i <= doom2; i++)
temp = doom1 * temp;
return temp;
}
Output
$ ./bin/simple_function
enter the value for the first : 2
enter the value for the second: 7
The value for my_power is: 128
you are trying to print "power" without parameter
printf("The value for power is %d",power);
you should do
printf("The value for power is %d",total);
or
printf("The value for power is %d",power(first,second));

Resources