My question is quite similar to the one here except that I’m working with C.
I wrote some code to rotate an unsigned int; that is, the function bitRotate()
(code below).
The function works very well when, instead of the printf
s and scanf
s, I directly put the literals I want to use, e.g. bitRotate(0xabcdef00,8);
in the main function.
However, when I pass x as an argument as in the following code, abcdef00 that was got from the user, the x gets corrupted to ab000000. I checked and double checked and debugged my code multiple times and I am pretty sure the error is in this part but I don’t understand why.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define WIDTH sizeof(unsigned int)*CHAR_BIT
unsigned int bitRotate(unsigned int, char );
int main()
{
unsigned int x;
char n;
while(1)
{
printf("Enter x: ");
scanf("%x", &x);
printf("Enter n: ");
scanf("%d", &n);
printf("%x\n", bitRotate(x,n));
}
return 0;
}
unsigned int bitRotate(unsigned int value, char n)
{
char un = abs(n);
unsigned int fallen = ~(0u);
if(un == WIDTH)
return value;
else if (un < WIDTH)
{
if (n < 0)
{
fallen >>= (WIDTH - n);
fallen = value & fallen;
fallen <<= (WIDTH - n);
value >>= n;
}
else
{
fallen <<= (WIDTH - n);
fallen = value & fallen;
fallen >>= (WIDTH - n);
value <<= n;
}
value |= fallen;
return value;
}
else
return 0;
}
The bitRotate
function is fine and so is the way you call it.
The actual culprit is here:
char n;
scanf("%d", &n); // <<<<<
You provide the wrong format specifier to scanf
which results in undefined behaviour. Your compiler most likely warned you about this.
The %d
format specifier needs an pointer to an int
(which usually takes 32 bits), but you provide the pointer to a char
which takes 8 bits. Therefore scanf
most likely clobbers the memory adjacent to the address of n
.
You want this:
int n;
scanf("%d", &n);