How do I scan and print an Unsigned Char in C? - c

I am trying to ask the user for an input, have that input be set as an unsigned char, and then print it out. For example, the input will ask me "Input x:" and I put in 0xABCD as the input. I need it to print out "0xABCD" as well.
Here's what I have so far:
unsigned char x;
printf("Input x:");
scanf("%s, &x);
printf("%u", x);
It gives me 0 instead of 0xABCD.
What am I doing wrong?

You need to use "%hhu" as the format specifier to read an unsigned char. See the table at http://en.cppreference.com/w/c/io/fscanf.
unsigned char x;
printf("Input x:");
scanf("%hhu", &x);
Note that if you use this format specifier, the input has to be a number. It cannot be a character. 65 will be a valid input but A won't.
Coming to your problem of wanting to use 0xABCD as input, that value is too large to fit into an unsigned char. You can use:
unsigned x;
printf("Input x:");
scanf("%x", &x);
To print that number as 0xABCD, you can use:
printf("0x%X\n", x);
If you don't mind the number being printed as 0xabcd, you can use:
printf("%#x\n", x);

A string is an array of characters terminated by '\0'. You're reading a string into a single character, which is undefined behavior.
Your code should really look something like this:
unsigned char x[64];
printf("Input x:");
scanf("%63s, x); /* use the size of buffer to prevent buffer overflows */
printf("%s", x);

In your code
scanf("%s, &x);
invokes undefined behavior. xis of type char and you cannot use %s to scan the value.
What you need is to define a char array at least to be able to hold your expected input.
If you like to have a second approach, you can do something like
scan the input as (unsigned) integer using %x
print the same using %#X format specifier.
See it live

In any ways "0xABCD" can't be treated as a 'char'. A char can store a 8 bit value, so from 0 to 255 (if unsigned), and the given number 0xABCD is equal to 43981.
You can read it as a string or read it as a hexadecimal value (which must be an unsigned). For this case an example:
unsigned int x;
printf("Number: ");
scanf("%x", &x);
printf("%d / %X\n", x, x);
will give:
Number: 0xABCD
43981 / ABCD
If treated as a string you will have to treat it an other way (sscanf…).

there is no char equivalent, use int instead.
int main(){
unsigned int x;
printf("Input x:");
scanf("%x", &x);
printf("\n%d (%#x)\n", x);
}

Related

Why in C does taking input using int format to a char change the value of another char variable?

I took input in %d format into a character using scanf() because I didn't want more than 8 bits. But doing so changed the value of another char variable.
Code:
#include <stdio.h>
int main() {
char a;
char b;
printf("Enter a: ");
scanf("%c", &a);
printf("a = %c\n", a);
printf("Enter b: ");
scanf("%d", &b);
printf("\na = %d\n", a);
printf("b = %d\n", b);
}
Output:
Enter a: c
a = c
Enter b: 56
a = 0
b = 56
Screenshot
scanf reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments.
scanf("%d", &b);
With %d you are storing an integer into the char variable that can not hold an integer.
the Variable now grows into the other variable in stack above it.
if you compile with the flag "-fstack-protector-all" you should get the
*** stack smashing detected *** error on execution.
The formatting directives in a scanf format string indicate not just how to match the input, but also the type of the corresponding variable in which the resulting value is to be stored. If you pass a pointer to an object of a different type than the corresponding directive expects then you reap undefined behavior.
That's true even for a simple signedness mismatch, but in your case you have a size mismatch. For a %d directive without a size modifier, scanf expects to write the scanned integer value in an object of type [signed] int. If the pointer you pass instead points to a char, and if, as is the case in most implementations, int is larger than char, then it is particularly likely that the resulting undefined behavior manifests in unwanted ways, such as by producing changes in the values of other variables.
If you want to scan a number as a char-sized integer, then you should
Declare the variable as either signed char or unsigned char, not default char, and
Use the correct conversion specifier and size modifier for the chosen data type.
For example,
unsigned char b;
scanf("%hhu", &b);
%u is the format directive for an unsigned integer, and the hh modifier instructs scanf that the destination variable is the size of a char / signed char / unsigned char.
If you want a signed integer then it would be similar, but with the %d formatting directive:
signed char b;
scanf("%hhd", &b);
As a matter of style, do not use default char for numeric data, even if you are confident that the range of values you need to support is a subset of the intersection of the ranges of signed char and unsigned char. Especially so if you plan to use it with formatted I/O functions, because it is implementation-specific whether %hhd or %hhu is the correct directive for a default char.
I agree with the side effect you indicated. This happens when the compiler loads variables in memory one after the other. For example, I examined the change in variable a when a sufficiently large number is typed in variable b. I changed the code as follows.
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
char a, b;
printf( "Address (a): %p\tAddress(b): %p\n", &a, &b);
printf( "Enter the values (a, b): " );
scanf( "%c, %d", &a, &b);
printf( "Value (a): %d\tValue (b): %d\n", a, b);
return EXIT_SUCCESS;
}
Then, when I tested the code, I realized the consequences of this side effect.
The tested code is interpreted in the image below.

Why the below code is giving different output when variable type is different?

//o/p when i/p is 16 and 2 is 4 and if variable is int then o/p will be 20;
#define SETBIT(A,B) A|1<<B
int main(){
char n,pos;
printf("Enter a value");
scanf("%d",&n);
printf("Enter position");
scanf("%d",&pos);
printf("Value after setting %d",SETBIT(n,pos));
}
For the *scanf functions, the d conversion specifier expects its corresponding parameter to have type int *; if that's not the case, then the behavior is undefined, and pretty much any result is possible.
If you want to use char for pos and n, then you must use %hhd instead of %d in the scanf call.

query regarding sprintf() and scanf()

Take for example
int i=10,j;
float b=3.14,c;
char str[30];
sprintf(str,"%d%f",i,b);
sscanf(str,"%d%f",&j,&c);
printf("%d ----- %f\n",j,c);
OUTPUT :- 103 ----- 0.1400000
As you can see, initially i=10 and b=3.14.
I want that j=10 and c=3.14 by using sprint() and sscanf().
The problem I am facing is that the compiler assigns j=103 and c=0.140000.
Is there any way to get rid of this problem in sscanf()?
Add one space to sprintf. Change:
sprintf(str,"%d%f",i,b)
to
sprintf(str,"%d %f",i,b)
Aside: It would be also safer to use snprintf here:
snprintf(str, sizeof str, "%d %f", i, b)
The best way will be to separate the numbers, using a different sign, but if you know that the first int is 2 chars long you can specify it:
sscanf(str,"%2d%f",&j,&c);
// ^^
You are missing a space
Change
sprintf(str,"%d%f",i,b);
to
sprintf(str,"%d %f",i,b);
#include <stdio.h>
int main()
{
int i=10,j;
float b=3.14,c;
char str[30];
sprintf(str,"%d %f",i,b);
sscanf(str,"%d%f",&j,&c);
printf("%d ----- %f\n",j,c);
return 0;
}
output
~ > ./a.out
10 ----- 3.140000
The %d conversion specifier in sscanf will match any number of contiguous numeric characters in the buffer pointed to by str till it encounters a non-numeric character which it can't match. This will cause the integral part of the float to be read as part of the int value. Therefore you must have a way to separate where you integer ends and float starts in the string str. You can put any non-numeric character as a sentinel to separate int value from the float value.
int i = 10, j;
float b = 3.14, c;
char str[30];
// a # to separate the two values, can be any non-numeric char so that it
// is not mistaken for a digit in the int or float value
sprintf(str,"%d#%f", i, b);
// match the separator character to read int and then float
sscanf(str, "%d#%f", &j, &c);

Can scanf() store values?

Hi I am now learning the C language and I have a little problem with a exercise of the book I read. My code is this:
#include<stdio.h>
int main()
{
unsigned char one=0;
unsigned char two=0;
printf("Quantity 1 = ");
scanf("%d",&one);
printf("Quantity 2 = ");
scanf("%d",&two);
printf("The value is %d",one);
return 0;
}
Why when I am trying to see the value of one the initial value appears and not the value after the scanf?
You need to use int type in conjuction with %d specifier, and char with %c specifier. And %u with unsigned integers.
#include<stdio.h>
int main()
{
unsigned int one=0; unsigned int two=0;
printf("Quantity 1 = ");scanf("%u",&one);
printf("Quantity 2 = ");scanf("%u",&two);
printf("The value is %u",one);
return 0;
}
Basicaly, scanf will try to read integer from input and it will try to store it inside memory location that is not large enough, so you will have undefined behavior.
You can find good reference here.
However, if you try to use character for an input type, you may want ask yourself why you won't get a chance to enter a second Quantity (if you type 4 and press enter). This is because second scanf will read enter key as a character. Also, if you try to type 21 (for a twentyone), it will fill the first value with 2 and second with 1 (well, with their ASCII values).
So, be careful - be sure that you always choose the right type for your variables.
Never use scanf.
Never use scanf.
Seriously, never use scanf.
Use fgets (or getline, if you have it) to read an entire line of input from the user, then convert strings to numbers with strtol or its relatives strtod and strtoul. strsep may also be useful.
Check if scanf() is working properly by reading its return value. For quickstart, read the details about scanf() at this link.
What you are doing is inputting a integer using "%d" into an unsigned char variable, therefore scanf() may not be working as it should.
Change
unsigned char one=0; unsigned char two=0;
to
unsigned int one=0; unsigned int two=0;
and also use %u instead of %d then it will print the value after scanf().
You declared the variable one to be a char:
unsigned char one=0;
But then you told scanf to read an int:
scanf("%d",&one); /* %d means int */
Int is bigger than char (typically 4-bytes vs. 1-byte), causing the problem you describe.
Change your scanf to:
scanf("%c",&one); /* %c means char */
Then when you print out the value, also print a char:
printf("The value is %c",one); /* %c means char */

Convert hex scanned (scanf) from an unsigned int array into decimal

I'm here trying to convert 4-digit hexa into dec but didn't succeed.
Here is a my code.
unsigned int array[4];
printf("Type in 4-digit hexa: \n");
scanf("%x", &array);
while(getchar() != '\n');
printf("Your number in dec is %u \n", array);
I don't know what's wrong with it but it just wouldn't give out the correct dec output.
Like when I put in EEFF, it's supposed to give out 61183 but the program kept on printing out 65518.
Where's this number from? What's wrong with my code? I used unsigned int according to my consideration that FFFF is equals to 65385 and the range for unsigned int is 0 to 65535. There should be no problem with the range of data and I also used %u with it.
The only thing I can think of right now after I've done some searching is that this problem might has sth to do with the size of unsigned int to int or sth.
I read the explanation but didn't quite understand.
I know, this might be a duplication but I'm here asking for an easier explanation
of why this doesn't work. To be honest, I'm an absolutely newby for both this site and programming so please go easy on me with the coding. FYI, I don't really know anything outside of stdio.h .
You are passing a pointer, array, to printf(). There is no need for an array here, what you're trying to scan and print is a single number.
unsigned int number;
printf("Type in 4-digit hex:\n");
if (scanf("%x", &number) == 1)
printf("Your number in dec is %u \n", number);
Also note that it's considered a good idea to check if scanf() succeeds or not, by inspecting the return value.
You don't need an array for that:
unsigned int val;
printf("Type in 4-digit hexa: \n");
scanf("%x", &val);
printf("Your number in dec is %u \n", val);
a. print array[0], not array.
(optional) b. scan to array, not to &array.
c. what is the point of the getchar()?
No, you must input as string to a point of characters. After that, you convert to number.
Ex
char *str=char[10];
int i=0,num=0;
printf("Type in 4-digit hexa: ");
scanf("%s",str);
for(i=0;str[i]!='\0';i++)
if(str[i]>='0' && str[i]<='9') num=16*num+str[i]-'0';
else if(str[i]>='a' && str[i]<='f') num=16*num+str[i]-'a';
else if(str[i]>='A' && str[i]<='F') num=16*num+str[i]-'A';
printf("Dec is %d",num);

Resources