Printing multiple ints outputs 0 - c

I'm practicing programming in c, but I've come across an issue that I can't seem to figure out. I have a printf statement with two markers for two different int values. No matter what the first int is, it prints 0, but the second int prints normally. Here's the code:
#include <stdio.h>
#include <stdlib.h>
int a, temp;
int toBinary();
int toDecimal();
int main()
{
char c;
for(;;)
{
scanf("%d",&a);
scanf(" %c",&c);
switch(c)
{
case 'a' :
printf("%d converted to binary: %d\n",a,toBinary());
break;
case 'b' :
printf("%d converted to decimal: %d\n",a,toDecimal());
break;
case 'c' :
printf("EXIT\n");
return 0;
break;
default :
printf("ERROR c value: %c\n",c);
return 0;
}
}
}
int toBinary()
{
if (a == 0)
return 0;
else
{
temp = a;
a /= 2;
return (temp % 2 + 10 * toBinary());
}
}
int toDecimal()
{
int res=0, base = 1, rem;
while (a > 0)
{
rem = a % 10;
res = res + rem * base;
a /= 10;
base *= 2;
}
return res;
}
The problem is that the printf statements in the first two cases ignore the actual value of int a, but it works normally for the value of the two functions. I'm not sure what's wrong, as a is given a value before, in the scanf statement, and I am using the proper marker in the text.

Since the order of argument evaluation is unspecified, this is undefined behavior.
The simplest fix would be to save a copy of a in a different variable, and print that.
int a_copy = a;
printf("%d converted to binary: %d\n",a_copy,toBinary());
But it would be better if the function didn't use a global variable in the first place.
int toBinary(int a)
{
if (a == 0)
return 0;
else
{
return (a % 2 + 10 * toBinary(a / 2));
}
}
Then you would do:
printf("%d converted to binary %d"\n, a, toBinary(a));

If a is modified in either toBinary() or toDecimal(), it's an UB.
The order of argument evaluation in one function call is unspecified. Some compilers evaluate them L->R (like GCC), some others do it R->L (like VC).
Try this and you'll find it out:
printf("%d %d %d\n", a, toBinary(), a);
printf("%d %d %d\n", a, toDecimal(), a);

The value of a in the function toBinary() gets reduced to 0 due to presence of the statement a /= 2; and it is getting recursively executed.
Hence your printf statement prints 0 for the value of a.
As #Barmar suggested, it's a good coding practice to use local variables rather than global variables inside a function.

Related

How to add the values of c?

#include <stdio.h>
int main() {
// Write C code here
int a, b = 1, c, d;
printf("Value of a:");
scanf("%d", &a);
while (b < a) {
c = b * a;
printf("%d", c);
b++;
}
return 0;
}
I was trying to find the factorial of a number but I don't know how to add the values.
It's written in C.
There are some problems in your code:
the expression c = b * a; computes an intermediary result, but not a useful one. You should compute c = c * b; multiplying the current factorial by the next integer to get the next factorial.
for the expression c = c * b; you must initialize c to 1 before the beginning of the loop.
printf("%d", c); outputs just the digits. You should output a space or a newline to separate the numbers.
scanf("%d", &a) may fail to convert a number from user input, for example if the user typed A. a will stay uninitialized, causing undefined behavior when you use it in further expressions. You should test that scanf() succeeded and returned 1, the number of successful conversions.
Here is a modified version:
#include <stdio.h>
int main() {
int a, b = 1, c = 1;
printf("Value of a:");
if (scanf("%d", &a) == 1) {
while (b < a) {
c = c * b;
printf("%d\n", c);
b++;
}
}
return 0;
}
It is recommended to use the for loop to group the initialization, increment and test of the loop variable in a single place:
#include <stdio.h>
int main() {
int a;
printf("Value of a:");
if (scanf("%d", &a) == 1) {
int c = 1;
for (int b = 1; b < a; b++) {
c = c * b; // one can also write c *= b;
printf("%d\n", c);
}
}
return 0;
}

My input in scanf is not working, process is returned and I don't get any output

The Fibonacci series is not obtained on running this program. The whole process terminates after giving input in scanf.
#include <stdio.h>
#include <stdlib.h>
int fibonacci(int);
int main()
{
int n, i = 0, c;
printf("Print the fibonacci series");
scanf("%d", n);
for (c = 1; c <= n; c++)
{
printf("%d\n", fibonacci(i));
i++;
}
return 0;
}
int fibonacci(int n)
{
if (n = 0)
return 0;
else if (n = 1)
return 1;
else
return (fibonacci(n - 1) + fibonacci(n - 2));
}
With scanf you need the give the address of the variable.
scanf("%d",&n); <= need to give the address of the integer
You can find some examples here:
http://www.cplusplus.com/reference/cstdio/scanf/
As you have already been told in Robert's answer, scanf expects an address for each format specifier. So, if format specifier %d is provided, the address of an integer is expected: scanf will write the value there.
If n is the variable containing the integer, &n is its address. Passing something that is not an address causes trouble: it is undefined behavior and will likely cause a segmentation fault.
There are also some problems in your Fibonacci generator. I suppose you want to print the n-th number in the sequence, but you iterate n times calling fibonacci() function (which only returns the last value) always with parameter i, which value is 0.
In fibonacci function you try to check for the exit conditions, but pay attention:
if (n = 0)
return 0;
doesn't check the value of n; it performs an assignment (the value of n will be 0 and the condition will be false). So it will proceed to the next "test"
if (n = 1)
return 1;
It is an assignment as well, 1 is assigned to n so the condition is true and 1 is returned. That's why you see 1 n times.
In order to make it work
correct the scanf issue
pass c to fibonacci()
correct the function so that the value is tested (== instead of =)
#include <stdio.h>
#include <stdlib.h>
int fibonacci(int);
int main()
{
int n, c;
printf("Print the fibonacci series\n");
scanf("%d", &n);
for (c = 1; c <= n; c++)
{
printf("%d\n", fibonacci(c));
}
return 0;
}
int fibonacci(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return (fibonacci(n - 1) + fibonacci(n - 2));
}
You missed the & sign in the scanf statement, and also , I think you got confused with the assignment operator = and logical equal ==, in the Fibonacci function.
#include <stdio.h>
#include <stdlib.h>
int fibonacci(int);
int main()
{
int n, i = 0, c;
printf("Print the fibonacci series");
scanf("%d", &n);
for (c = 1; c <= n; c++)
{
printf("%d\n", fibonacci(i));
i++;
}
return 0;
}
int fibonacci(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return (fibonacci(n - 1) + fibonacci(n - 2));
}

Two integers and an operator. Error, not doing what it needs to do in other compiler

The problem here is that it works on vscode but it doesn't in onlinegdb.com. I think there's some error in my code that I overlook but I can't find so I am hoping someone out there would help me out. thank you very much.
btw there's no warning error in onlinegdb.com but when I try to run it, the result is not right so that's the issue.
#include <stdio.h>
#include <string.h>
//This is a FUNCTION PROTOTYPE :)
int check(char op);
int calculate(int a, int b, int c);
char * print_operators(int op);
int main()
{
// create a variable to store the integers.
int num1,num2;
// create a variable to store the operator that the user wants to use.
char operator;
//prompt for the first integer.
printf("Enter first Integer: ");
scanf("%d", &num1);
// prompt to enter the operator to be used.
do
{
printf("Enter operator, + as sum, - as difference, * as product, / as quotient: ");
scanf(" %s", &operator);
}
// keep prompting the user until he input the correct operator using the check function call.
while(check(operator) == -1);
// prompt for the second integer.
printf("Enter Second Integer: ");
scanf("%d", &num2);
// calculate the total result using the calculate function call and store it to a variable called total.
int total = calculate(num1, num2, check(operator));
// using the print_operators to know what is the operator being used to store it in variable operators in a string form.
char * operators = print_operators(check(operator));
//output of the result.
printf("The %s is: %d\n", operators, total);
return 0;
}
// this is function definition of check to verify if the input is valid and if it's valid then covert it to integer in an order.
int check(char op)
{
// creating a char array to store the symbol of the operators.
char operations[] = {'+', '-', '*', '/'};
// this variable is to be use in a for loop so that I don't need to use a magic number in for-condition.
int size = sizeof(operations);
// looping to convert the operator to integer from 0 to 3 and storing the operator in its ordered form.
// 0 representing +, 1 representing -, 2 representing *, and 3 representing /.
for (int i = 0; i < size; i++)
{
if(op == operations[i])
{
return i;
}
}
// else print invalid and return the value of -1 representing its not valid.
printf("INVALID\n");
return -1;
}
// this function definition of calculating is to calculate the two integers using the operator that is already converted to an integer.
int calculate(int a, int b, int c)
{
// create a variable to store the result of the calculation.
int equal;
// if the operator is 0 then do addition.... and so on.............
if (c == 0)
{
equal = a + b;
}
else if (c == 1)
{
equal = a - b;
}
else if (c == 2)
{
equal = a * b;
}
//else if its not 0, 1, or 2 then its difinitely 3.
else
{
equal = a / b;
}
// then return the result.
return equal;
}
/* This function definition of print_operators is to return the operator as a string so that I can use it in print without manually coding it. */
char * print_operators(int op)
{
char * operators[] = { "sum", "difference", "product", "quotient" };
int size = sizeof(operators);
for (int i = 0; i < size; i++)
{
if (i == op)
{
return operators[i];
}
}
// Some compiler needs a return value even if it didn't reach so I just did this just in case your compiler is different from mine.
//although this is not necessary for my compiler, I've checked it in the cloud server, and there's an error if this is not included.
char * total = "total";
return total;
}
/* Example if I want to output the 1+2 then my output is "The sum is: 3". Notice that the sum is not constant cuz maybe if I what to use subtraction then I want it to output as "The difference is: 1". */
First of all, scanf(" %s", &operator); should be scanf(" %c", &operator); operator because you are expecting a single character here, not a string. It can potentially corrupt the stack.
I guess that should fix your issue with onlinegdb.
There are also other issues and possible simplifications. Such as your print_operators function which may be written simply as:
char *print_operators(int op)
{
char *operators[] = { "sum", "difference", "product", "quotient" };
/* sizeof(array) gives the total size of your array in bytes, not the number of elements in your array, so divide it by the size of each element to get num of elements */
int count = sizeof(operators)/sizeof(char *);
/* Since you already have the operator converted to a number in your check() function, just use it directly as index here */
if(op < count)
return operators[op];
else
return "total";
}
"Some compiler needs a return value"
All compilers need a return value if you have specified that a function returns a value other than void. Some compilers, however, may not warn you that you are not returning a value and lead you into undefined behaviour, which is not what you want.

scanf confusion with type error

I just make a program to guess some random pairs in an array,if guess right, delete this pair.
I met a problem that I can only type integer number.Everytime I tried to type like * ,the program will crash. I use a condition like:
if (scanf("%d",&temp)==1)
to try to fix my problem, but it really does'nt work.
here is my code and please give me some help:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int r[4]; //random
int s[8]; //store
char c[8]; //cover
int g[8]; //guess
int i;
int round=0;
int left = 4;
int point = 0;
int clear_index[2];
int temp;
// generate random number
for (i=0;i<4;i++)
{
r[i] = (rand()%10)+1;
s[i] = r[i];
s[i+4] = r[i];
}
// show the default number
printf("[show] ");
for (i=0;i<8;i++)
{
printf("%d ",s[i]);
c[i] = '*';
}
printf("\n");
while(left>0)
{
// print left
printf("[cover] ");
for (i=0;i<8;i++)
printf("%c ",c[i]);
printf("\n");
//guess
printf("[guess] ");
for(i=0;i<8;i++)
{
if (scanf("%d",&temp)==1)
g[i] = temp;
if (g[i] == s[i])
{
printf("v\n");
clear_index[point] = i;
point++;
}
}
if (point == 2)
{
for (i=0;i<2;i++)
c[clear_index[i]]=' ';
left-=1;
point = 0;
}
round+=1;
//left-=1;
}
printf("you won in %d round",round);
}
You get the segmentation fault, because, in case, you did not enter an integer, scanf will not return 1, and then, using g[i] will invoke undefined behavior.
FWIW, g is a local automatic array variable, and unless initialized explicitly, will have indeterminate value. Attempt to read the value will invoke the UB.
Solution:
Always initialize the local variables.
In case scanf() fails, you need to eat up the invalid input using some loop like while (getchar != '\n'); before you proceed to take the next input.
You are reading a number but the user can place a digit. To prevent this you can use the function atoi() from the library stdlib.h. It converts a string to a integer, if the integer is just number digits, it'll convert it to a integer. If it is a character it will return 0. So you just need to prevent the occurrence of a 0 after the atoi() function is called.

In C How to use leftmost digit from an integer

I was wondering how to reverse my output to match entered number.
Example if user entered 543210, I want the output to be: Five Four Three Two One Zero. But instead it's reversed and I can't figure out how to reverse it.
I can't use loops or anything else.
Code:
int main(void){
int value;
int digit;
printf("enter:");
scanf("%i", &value);
while(value)
{
digit = value % 10;
value = value / 10;
if(digit != 0)
{
switch(digit)
{
case 0:
printf("zero ");
break;
case 1:
printf("one ");
break;
case 2:
printf("two ");
break;
case 3:
printf("three ");
break;
case 4:
printf("four ");
break;
case 5:
printf("five ");
break;
case 6:
printf("six ");
break;
case 7:
printf("seven ");
break;
case 8:
printf("eight ");
break;
case 9:
printf("nine ");
break;
}
}
}
return 0;
}
Exmaple: If user entered 1234
Output would be: four three two one.
How would I fix it to be: One Two Three Four.
Since you've said that you aren't allowed to use loops, then recursion really is the thing that you are probably being expected to use. I personally am not sure if it would be right to not consider a recursion as a loop, but whatever.
You are using a while there, which also is a loop. If you are allowed to use loops, then you could just do the following, easy-to-understand modification in your code, and get the output you desire:
...
int input; // <-- added this
int value;
int digit;
printf( "enter:" );
scanf( "%i", &input ); // <-- notice the change in variable usage
value = 0;
while ( input ) {
value = 10 * value + input % 10; // adds the last digit of input to value from right
input /= 10;
}
while ( value ) { ... }
...
If you aren't allowed to use loops, then you probably are expected to use a special function, a function which outputs a specific value for a single case, and returns back to itself in any other case. You need a recursive function. Examine this simple example:
// This is in maths, not C
f(x) = 2x + 1 for all integer x >= 0
Out of many ways, this one way to describe the function which maps 0 to 1, then 1 to 3, then n to 2n + 1. If we wanted to define the exact same function recursively:
// In maths
f(x = 0) = 1 for x = 0
f(x > 0) = f(x-1) + 2 for integer x > 0
You see what's going on in there? It's saying that each subsequent f(x) is 2 greater than the previous one f(x-1). But more importantly, the function is calling itself! If you look closer, the called function f(x-1) will also call itself:
f(x) = f(x-1) + 2
f(x) = f(x-2) + 2 + 2
f(x) = f(x-3) + 2 + 2 + 2
...
// all these are the same
All this calling deeper and deeper has to end somewhere, and that somewhere is when f(x-...) is f(0), which has been explicitly defined to be 1.
This is what recursion is all about. Let me write out the examples I gave above in C:
// non-recursive version
int fnonrec( int x ){
return 2 * x + 1;
}
// recursive version
int frec( int x ){
if ( x == 0 )
return 1; // explicit return value for f(0)
else // redundant else, hehe
return frec( x - 1 ) + 2;
}
Definitions of the functions really look similar to how they were defined in maths, don't they? Yeah, well, I don't think giving you the answer for your question would be nice of me. All I can say is that you can print things in reverse really nicely with recursive functions.
//store user input to int variable "value"
char str[15];
sprintf(str, "%d", value);
You can then use the strrev function to reverse the string array. Manipulate it from there.
#include <stdio.h>
void print(int v){
static char *numbers[] = {
"zero","one","two","three","four",
"five","six","seven","eight","nine"
};
int digit = v % 10;
int value = v / 10;
if(value){
print(value);
printf(" %s", numbers[digit]);
} else
printf("%s", numbers[digit]);
}
int main(void){
int value;
printf("enter:");
scanf("%i", &value);
print(value);
return 0;
}
Example using recursive function and numbers from the parameters :
#include <stdio.h>
void display(char c)
{
char *numbers[] = {
"zero","one","two","three","four",
"five","six","seven","eight","nine "
};
printf("%s ", numbers[c]);
}
int aff_num(char *c)
{
if (*c == '\0')
return (0);
display(*c-48);
aff_num(++c);
return (1);
}
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("Need numbers\n");
return (-1);
}
aff_num(argv[1]);
return (0);
}
I'm a python hacker and I almost never program in C. that being said:
#include <stdlib.h>
#include <stdio.h>
int highest_power_of_ten(int value){
int exponent = 0;
int tens = 1;
while(value > tens){
tens *= 10;
exponent += 1;
}
return exponent-1;
}
int pow(int base, int exponent){
if (exponent == 0)
return 1;
int temp = base;
while(exponent > 1){
base *= temp;
exponent -= 1;
}
return base;
}
int main(int argc, char** argv){
char* digits[] =
{"zero","one","two","three","four","five","six","seven","eight","nine"};
int value, n, exp, x;
scanf("%i", &value);
while(highest_power_of_ten(value)>0){
exp = highest_power_of_ten(value);
x = pow(10, exp);
n = value/x;
printf("%s ",digits[n]);
value -= n*x;
}
printf("%s\n", digits[value]);
//system("PAUSE"); for windows i guess
return 0;
}
Another method to get the digits in the right order:
E.g. To get the digit at 1st position in 123 divide 123 by 100, to get 2nd - 123 / 10, to get 3rd 123 / 1. That equals: value / 10^(index of desired digit)
So what we have to do is
Get the length of the (remaining) number by calculating log10(value).
Then get the (remaining) first (most significant) digit by dividing value by 10^length (length of 1.)
calculate value := value - 10^length and start from 1, unless the result is 0 (mind handeling numbers that end on 0).
while (value)
{
len = log10(value);
digit = (int) value / pow(10, len);
value -= pow(10, len);
}
And your code does never enter case 0. To fix that just leave the if(digit != 0) - that's what I meant when I wrote "mind the 0").
if(digit != 0) // enters if digit is not 0
{
switch(digit)
{
case 0: // enters if digit is 0
...
}
}

Resources