C- printf hex values giving unexpected output - c

I'm trying to learn some of the basics of C and I have been reading nonstop about gets/fgets/puts/scanf and can't seem to get this right...
My code is:
#include <string.h>
#include <stdio.h>
#define BUFF 256
void main()
{
char s[BUFF];
fgets(s, BUFF, stdin);
s[strlen(s)-1]='\0';
printf("%x %s %d", s, s, strlen(s));
}
I'm trying to get the hex format of the variable s to print, my input is AAAA and the output I want is 41414141 AAAA 4, the output I'm getting is 12fe80 AAAA 4.
I thought I needed to cast s (as a u int) for the hex interpretation, but that didn't work either.
I would really appreciate an explanation on this as well as help, I'm really trying to learn this.
Thank you!

void main()
This isn't your problem, but the correct definition is
int main(void)
void main() is useful mostly as a tool to detect C textbooks written by incompetent authors.
printf("%x %s %d", s, s, strlen(s));
This has undefined behavior:
"%x" requires an argument of type unsigned int; you're giving it a char* (the array expression s is converted to a pointer to its first element).
%d requires an argument of type int; you're giving it a size_t. Either convert it to int, or use %zu.
If you want to print a hexadecimal representation of the contents of the string s, there's no direct way to do that. You'll just have to loop over the characters contained in s and print the value of each one in hexadecimal. (You should cast each char value to unsigned int so it works properly with the "%02x" format.)

%x works on numbers. You're passing in a pointer to a string. So in this case printf() is interpreting the pointer (memory address) as a number and printing that address in hex format. Sounds like you just want to print the ASCII values, in hex, of each character in the input:
for (int i = 0; i < strlen(s); ++i)
printf("%02x", (unsigned) s[i]);

Try this
$ cat hello.c
#include <string.h>
#include <stdio.h>
#define BUFF 256
int main()
{
int i = 0; /* a counter */
char s[BUFF];
fgets(s, BUFF, stdin);
s[strlen(s)-1]='\0';
while (i < strlen(s)) { /* to get the character(s) in s */
printf("%x", s[i]); /* as hex */
i++;
}
printf(" %s %d\n", s, strlen(s)); /* as before */
}
$ gcc hello.c -o hello && echo "AAAA" | ./hello
41414141 AAAA 4

The hex value you are printing is the address of the string, not the contents (since s is a char*).
To see the full contents of the string as hex bytes, you will have to do something like this:
int n = strlen(s);
for(int ii=0; ii<n; ii++) printf("%02x", (unsigned int) s[ii]);

#include <stdio.h>
#include <string.h>
main() {
char a[]="AAAA";
printf("%x%x%x%x %s %d", a[0],a[1],a[2],a[3],a, (int)strlen(a));
}

print all the array index one by one.
printf("%x ", *s);
printf("%x ", *(s+1));
....
....

Related

Why I am not receiving a hexadecimal number as output when I print a pointer address with %p?

I have written a program while learning pointers in c and facing a problem. My code was to print the address of the variable which should be a hexadecimal number. But why I am receiving an integer number instead of a hexadecimal number. Please help me out to print the hexadecimal number starting with "0x" . Thank you.
Note that my IDE was Visual Studio Code and the compiler I am using is GCC.
#include <stdio.h>
int main(void)
{
char *a = "abcd";
for (int i = 0; i<4; i++)
{
printf("%p\n",&a[i]);
}
}
Output :
00405064
00405065
00405066
00405067
I was expecting a number starting with "0x"
It's not defined what %p uses as a format to print the address.
However, it's common for it to be displayed in hexadecimal.
So, if you want to print the hexadecimal number of a pointer the most portable way I know of (C99 & above) is:
#include <stdio.h>
#include <inttypes.h> // PRIxPTR
int main(void) {
const char *a = "abcd"; // 'const' because a is not modifiable
for (int i = 0; i<4; i++) {
uintptr_t tmp = (uintptr_t)&a[i];
printf("0x%" PRIxPTR "\n", tmp);
}
}
Everything seems just fine in your code sample. I tested it on three different online compilers and produced expected output:
Output on compiler 1:
0x55cf7d06c004
0x55cf7d06c005
0x55cf7d06c006
0x55cf7d06c007
Output on compiler 2:
0x55dfc15c0004
0x55dfc15c0005
0x55dfc15c0006
0x55dfc15c0007
Output on compiler 3:
0x4005c0
0x4005c1
0x4005c2
0x4005c3
So, I guess is something in your IDE/compiler.

variable is losing its value in c program

This is written in 'c' and compiled with gcc. I'm not sure what else you need to know.
The smallest complete example I could put together is shown here. The variable 'numatoms' loses its value when it gets to line 23 (after the scanf()).
I'm stumped. Maybe it has something to do with scanf() overwritting the space for numatoms?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/*
*
*/
int main(int argc, char** argv) {
uint8_t numatoms;
uint8_t r;
char a[20];
do {
printf("NO. OF ATOMS?");
fflush(stdout);
scanf("%d", &numatoms);
printf("\r\n");
for(;;){
printf("value of numatoms is %u\r\n", numatoms);
printf("RAY?");
fflush(stdout);
scanf("%u", &r);
printf("value of numatoms is %u\r\n", numatoms);
if(r < 1)
break;
else {
printf("value of numatoms is %u\r\n", numatoms);
}
}
printf("CARE TO TRY AGAIN?");
fflush(stdout);
scanf("%s", a);
printf("\r\n");
} while (a[0] == 'y' || a[0] == 'Y');
return (EXIT_SUCCESS);
}
uint8_t is 8 bits long %u reads an unsigned int (probably 32 bits long).
You either need to make numatoms "bigger" (i.e. unsigned int) or read the correct size (see scanf can't scan into inttypes (uint8_t))
You should use macros for format specifiers for integer types defined in the header <inttypes.h>.
From the C Standard (7.8.1 Macros for format specifiers)
1 Each of the following object-like macros expands to a character
string literal containing a conversion specifier, possibly modified by
a length modifier, suitable for use within the format argument of a
formatted input/output function when converting the corresponding
integer type. These macro names have the general form of PRI
(character string literals for the fprintf and fwprintf family) or SCN
(character string literals for the fscanf and fwscanf family),217)
followed by the conversion specifier, followed by a name corresponding
to a similar type name in 7.20.1. In these names, N represents the
width of the type as described in 7.20.1.
The general form of the macro used for unsigned integer types with the conversion specifier u looks like
SCNuN
Here is a demonstrative program
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void)
{
uint8_t x;
scanf( "%" SCNu8, &x );
printf( "x = %u\n", x );
return 0;
}

Convert usigned integer( uint16_t) to string. Standard itoa base 10 is giving negative values

I need to convert uint16_t value to a string. I want the string to be a decimal respresentation of the number.
Example: uint16_t i=256 string: 256
I tried with itoa(i,string, 10) but when i value increases starts printing negative values.
I send the string via the Serial Port.(UART)
It is there some alternative?
Use sprintf with %u format for unsigned int:
uint16_t i = 33000;
sprintf(str, "%u", i);
You can try to use sprintf() for common "to string" conversions. For example:
#include <stdio.h>
#include <math.h>
int main() {
uint16_t i = 256;
char str[80];
int str_len = sprintf(str, "%d", i);
return(0);
}
For more info look at this article.

Printing atoi value of an uninitialised array

Simple question, below is my code. The number my compiler returns is 4219296. My question is: why? What is my code doing here?
#include <stdio.h>
char array[];
int main()
{
atoi(array);
printf("%d \n", array);
return 0;
}
The function atoi returns the converted value. This value needs to be stored. Here in the above program you are not storing the returned value. So there is no effect on the array variable.
Printing the array in decimal format gives you the address of the array. The program shall print the same value even without the atoi function. To confirm try this:
//...
printf("%d \n", array);
atoi(array);
printf("%d \n", array);
Output remains same.
Here that is printing the address of the starting position in of your array. If you use
a pointer you will get the value of that.
printf(" %d \n",*array);
Here atoi is doing nothing.
If i'm not wrong, you want to convert a string containg a numberic value into an integer.
In your code, because of char array[]; atoi() will face undefined behaviour. You need to pass some valid address to the API.
Also, instead of using atoi(), use the safer counterpart strtol().
Check the below code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ip[ ] = "12345";
char *err;
long int retval;
retval = strtol(ip, &err, 0);
printf("strng format : %s, int format %ld\n", ip, retval);
return 0;
}
O/P
[sourav#broadsword temp]$ ./a.out
string format : 12345, int format 12345
Also, if you change the ip to someting like char ip[ ] = "12A45";, then the o/p will look like
[sourav#broadsword temp]$ ./a.out
string format : 12A45, int format 12

How can I print the decimal representation of a character in c?

I am trying to figure out how to print the ascii value of a character in binary. Here is what I have done so far, but it does not work at all and I dont know why. Can someone of you C wizards help me??
#include <stdio.h>
int main(int argc, char** argv)
{
char myChar;
printf("Enter a character:\n");
scanf("%c", &myChar);
printf("Your character is %c\n", myChar);
printf("ASCII in BIN: %c\n", toBinary(myChar));
return 0;
}
char* toBinary(int decimalNumber)
{
char binaryValue[7] = "";
for (int i = sizeof(binaryValue); i >= 0; ++i)
{
int remainder = decimalNumber % 2;
decimalNumber = decimalNumber / 2;
binaryValue[i] = remainder;
}
return &binaryValue;
}
The %c format string will always interpret the corresponding printf argument as a character. In this case, its probably not what you want.
printf("ASCII in BIN: %d\n", myChar);
will print out the ascii code point of myChar just by telling printf to treat it as a number.
If you'd like to print out the string being returned by your toBinary function, you can do that with
printf("ASCII in BIN: %s\n", toBinary(myChar));
There's a good reference of the various % codes and what they mean here.
However, it's also worth noting that your toBinary function probably doesn't do what you want. This loop condition:
for (int i = sizeof(binaryValue); i >= 0; ++i)
will start at sizeof(int) and count up until it runs out of integers, then stop only because INT_MAX + 1 == INT_MIN. Because you're using i as an array index, this will almost certainly crash your program.
You also need to make sure to terminate the string you're generating with a '\0', as that is how subsequent calls to printf will recognize the string has ended.
And, as noted in other answers, your toBinary implementation is also returning a pointer to a memory address that will get automatically deleted as soon as toBinary returns.
You are returning address of local array.
This is both incorrect return type (char ** vs char *) and a bad thing to do at all.
printf("ASCII in BIN: %c\n", toBinary(myChar));
%c is to print a character.
And, there is no BOOL type in C, so you can change it in to a string, and pass the pointer to an array to printf("%s", pointer)

Resources