Solijoli
Solijoli

Reputation: 474

Hexadecimal number comparison?

I'm a new to C language and a bit confused about how hexadecimal, decimal numbers work. I am trying to work with maximum of 4 bytes, so 0xFFFFFFFF. I basically want the program to give an alert if any number is entered with 9 digits or higher. I have written a code as below but it still lets me input numbers bigger than 0xFFFFFFFF. What am I doing wrong? Thanks in advance!

int main()
{
uint32_t rgba;
printf("Enter rgba value: ");
scanf("%x", &rgba);
if (rgba > 0xFFFFFFFF){
    printf("Maximum number of 8 digits!\n");
}
else{
    rgba_values(rgba);
}
return 0;
}

Upvotes: 1

Views: 2394

Answers (4)

chux
chux

Reputation: 153447

As @Jongware commented, "You cannot check for a number larger than it is possible to store."

To detect if user input is outside the range of uint32_t rgba, code needs to understand that the user input has or will exceed that range.

Method 1: Use larger integer type: This method will detect "100000000" as too large an input, but will have trouble with numbers larger than "FFFFFFFFFFFFFFFF".

unsigned long long UserInput;
uint32_t rgba;
printf("Enter rgba value: ");
if (scanf("%llx", &UserInput) != 1) {
  puts("EOF or Scan Failure");
  return 1;
}
if (UserInput > 0xFFFFFFFFu) {
  puts("Range error");
  return 1;
}
rgba = UserInput;
rgba_values(rgba);

Method 2: Use fgets()/strtoul(). The following will work for input up to 99 char long (which includes the '\n').

uint32_t rgba;
char *buf[100];
printf("Enter rgba value: ");
if(fgets(buf, sizeof buf, stdin) == NULL)  {
  puts("EOF");
  return 1;
}
char *endptr = 0;
errno = 0;
unsigned long ul = strtoul(buf, &endptr, 16);
if (buf == endptr) {
  puts("No conversion");
  return 1;
}
if (errno || ul > 0xFFFFFFFFu) {
  puts("value out of range");
  return 1;
}
rgba = (uint32_t) ul;
rgba_values(rgba);

Other methods include counting the number of hexadecimal characters or converting user input 1 char at a time.

Upvotes: 2

elias-berg
elias-berg

Reputation: 559

What you could do is store the user-input into a char* first:

char rgba_str[20]; // 20 is an arbitrary larger buffer size
printf("Enter rgba value: ");
scanf("%s", &rgba_str);

Then check and see if the length of the string is greater than 9 digits:

if ( strlen( rgba_str ) > 8 )
  // Error

If not, turn rgba_str into a hexadecimal integer:

else
  rgba = strtoul(rgba_str, NULL, 16);

Upvotes: 0

chqrlie
chqrlie

Reputation: 144715

Check the return value of scanf: it returns 1 if and only if the input is a valid hexadecimal number without overflow. Note that this will only fit your purpose if the int is exactly 32 bits on your platform.

Upvotes: 0

ouah
ouah

Reputation: 145829

if (rgba > 0xFFFFFFFF)

rgba is a 32-bit unsigned integer value, the condition above is always false. A 32-bit unsigned integer value is always <= 0xFFFFFFFF.

Upvotes: 0

Related Questions