Why does printf give me the following output? - c

I'm working through The C Programming Language book and understand that if I had a line of code like:
int c;
printf("%d", c = 5);
I will get an output of 5, because (c = 5) has the value of the RHS value of the assignment.
In a similar way:
int c;
printf("%d", c = getchar(c));
will give me the integer value of the first char in the stdin buffer, because (c = getchar()) has the value of the RHS which is just the getchar() function.
I was playing around with it and used the following using VS Code:
#include <stdio.h>
int main()
{
int c, b;
printf("%d\t%d", c = (b = 7));
}
The output I get is:
7
6422376.
and not
7
7
Why is this? The second output is the same value (6422376) no matter whatever value I use for b, eg (b = 3).

The expression c = (b = 7) is a single expression, and as such a single argument passed to the printf function.
The second %d format specifier leads to undefined behavior as there is no second argument matching it.

because for second %d there is no matching argument as c=(b=7) is a single expression

Your code is not well-formed : you have only one parameter for printf when you should have two.

#include <stdio.h>
int main()
{
int c, b;
printf("%d\t%d", c = (b = 7),b);
}
you can try these code to print the value of b. There is only one parameter in your printf function, and 2 format specifier, so compiler assumes any garbage value for another %d.

Related

Extract an integer value from array and program without showing printf function

I want to extract a number from an array I introduce in the keyboard and convert it into one integer. My code is:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
int r, t, i;
char expressio[t];
char vector[50];
char rpn[t][4];
printf("Introduce the expresssion");
fgets(expressio, t, stdin);
t = strlen(expressio);
for (i = 0; i <= t; i++) {
if (isdigit(expressio[i])) {
r = atoi(expressio[i]);
vector[i] = rpn[0][r];
}
return 0;
}
}
I have this warning:
passing argument 1 of 'atoi' makes pointer from integer without a cast
How can i solve it?
Also, when I execute this program, it does nothing and it doesn't even print the "Introduce the expression". Why is this happening?
That warning means that you are passing a bad argument to the function. "atoi" is expecting an array of chars as argument, but you are passing a single char as argument here:
r = atoi(expressio[i]);
If you want to convert a single char into a number, you can do:
r = expressio[i] - '0';
If you look at the ascii table, you will notice that the ascii value of 0 is 48. If you substract 48 (or, like i did, the ascii value of 0) to your char expressio[i], you will get the corresponding number as an integer. Like this, if expressio[i] equals '8', then r will equal 8.

How the value of an int being printed as a char?

In below program ,How is int being converted into char by printf()? Is it being demoted implicitly?
#include<stdio.h>
int main()
{
int c=2;
printf("%c",c);
}
The code is working fine! You will just get the ASCII character for c.
Let´s look on another example:
int c;
for (c = 97; c < 123; c++)
{
printf("%c",c);
}
This code would generate the following output:
abcdefghijklmnopqrstuvwxyz
If the value of c is greater than the biggest value of char the output just starts from the begin. This means c = 1 would generate the same output as c = 257.
In your code,
printf("%c",c);
works, because, as per the C11 standard, chapter §7.21.6.1, The fprintf() function, the %c format specifier,
c
If no l length modifier is present, the int argument is converted to an
unsigned char, and the resulting character is written.
So, the value held by c will get converted to an unsigned char, which then will be printed out using %c format specifier.

What happens when using scanf("%d", &c) while c is a char?

the code is like this:
char c;
scanf("%d", &c);
inputting 3...
My guess is that when 3 is inputted, it is as type int;
and then type-demoted to char and assigned to c;
I print the value of c in specifier %d yielding 3, seems to be as expected;
but printing the value of c with specifier %c yields --a blank-- on the terminal;this is one question...(1);
to test more I furthermore declare a variable ch with type char and initialized it like this:
char ch = 1;
and the test is like this:
(i&j)? printf("yes") : printf("no");
and the result is "no"
I print out the value of i&j, and it is 0
but 1&3 should be 1? this is another question....(2);
my question is (1) and (2)
You're actually invoking undefined behavior doing that.
By using the format string %d, you're telling scanf to expect an int* as a parameter and you're passing it a pointer to a single character. Remember that scanf has no further type information on what you're passing it than what you're putting in the format string.
This will result in scanf attempting to write an int sized value to memory at an address that points to a char sized reservation, potentially (and for most architectures) writing out of bounds.
After invoking UB, all bets are off on your further calculations.
Suppose that scanf() were not a varargs-function, but a plain ordinary function taking a pointer-to-int as the 2nd argument:
int noscanf(char *format, int *ptr)
{
*ptr = 42;
return 1;
}
int main(void)
{
char ch;
int rc;
// This should *at least* give a warning ...
rc = noscanf("Haha!" , &ch);
return 0;
}
Now, scanf() is a varargs function. The only way for scanf() to determine the type of the (pointer) arguments is by inspecting the format string. And a %d means : the next argument is supposed to be a pointer to int. So scanf can happily write sizeof(int) bytes to *ptr.
I can't see a variable jthere. So i&j will be 0. And yes, if i == 1 and j == 3 then i & j == 1.
(i&j)? printf("yes") : printf("no");
statement gives the output yes,for i=1 and j=3.
And for (1) question ASCII 3 is for STX char which is not printable.

C char appears as int when compiling

I'm learning C, and have been trying to make a program that takes user input, and removes any double spaces in it, then prints it out again. We have not done arrays yet so I need to do this char by char. This is my code:
#include <stdio.h>
main()
{
char c;
int count;
count = 0;
while ((c = getchar()) != '\n')
if (c == ' ')
count++;
if (c != ' ')
count = 0;
if (count <= 0)
printf("%s", c);
}
This code does not work, however. The compiler returns the error
:15: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
Any help? I have no clue what I am doing wrong.
Use the %c format specifier to print a single char
printf("%c", c);
The %s format specifier tells printf to expect a null-terminated char array (aka a string).
The error message refers to c having type int due to default promotion of arguments (beyond the format string) passed to printf. This previous answer has a nice description of default promotion; this previous thread explains some of the reasoning for why default promotion is necessary.
You are using %s which is used for a string and which expects a terminating NULL character(\0)..
Using %c will print you char by char..
Your code has so many problems
First, you print a char with %s (which expects a char pointer, i.e. a string)
In C, char literals are of type int, so whether promoted or not, they're always int. In C++, char literals would be of type char, but after promotion like other answers said, again they'll be int. A plain char variable will also be promoted to int in expressions, and passed as int in vararg functions like printf. That's why the compiler warns you that argument 2 has type ‘int’, because it's expecting a char* and you're passing it an int
→ You must use %c to print a char
Your while loop's body is only the first if block, because in C block scope is defined by {}, not by indentation. So the code will run like this, which is not like what you intended
while ((c = getchar()) != '\n')
{
if (c == ' ')
count++;
}
if (c != ' ')
count = 0;
if (count <= 0)
printf("%s", c);
→ You need to put the code block in a pair of brackets. And using else instead of 2 separate ifs to make it more readable and faster (for dumb compilers)
while ((c = getchar()) != '\n')
{
if (c == ' ')
count++;
else
count = 0;
if (count <= 0)
printf("%s", c);
}
main() is wrong. The correct versions in C would be
int main(void)
int main(int argc, char **argv)
See What should main() return in C and C++?
c must be declared as int because getchar returns int. See Why must the variable used to hold getchar's return value be declared as int?
A minor point is that instead of int count; count = 0;, just initialize the variable while declaring int count = 0. Or better yet use an unsigned int, because count can't be negative

Converting ASCII code to a character value

I've just started learning how to program in C and I'm trying to make a program that accepts a number and uses it as an ASCII value to return the ASCII character associated with that value.
The program works when the parameters are predefined but when I introduce the scanf function it compiles but doesnt give me the same results.
Here is my code :
#include <stdio.h>
int main(void)
{
question2();
return 0;
}
int question2(void)
{
int myInt = 65;
scanf("%d", myInt);
char ch = myInt;
printf("%c",ch);
return 0;
}
Cheers and thanks for any help guys.
You need to pass the address of myInt to scanf() (the compiler should have emitted a warning for this):
scanf("%d", &myInt);
You should also check the return value of scanf() to ensure myInt was actually assigned to. scanf() returns the number of assignments made, which in this case is expected to be 1:
if (1 == scanf("%d", &myInt))
{
}
Note that int has a larger range values than a char so you should check that the value stored in myInt will fit into a char. There are macros defined in the header limits.h that you can use to check:
if (1 == scanf("%d", &myInt))
{
if (myInt >= CHAR_MIN && myInt <= CHAR_MAX)
{
printf("%c\n", (char) myInt);
}
else
{
printf("%d out-of-range: min=%d, max=%d\n",
myInt, CHAR_MIN, CHAR_MAX);
}
}
The compiler should have also emitted an implicit function declaration warning with respect to question2(). To correct, place the definition of question2(), or a declaration for question2(), prior to main().

Resources