Правильный ввод и проверка шестнадцатеричных значений - PullRequest
3 голосов
/ 06 декабря 2011

Я пытаюсь создать простую программу или функцию, которая будет принимать пользовательский ввод, который может быть действительным шестнадцатеричным числом.

Я пытаюсь найти способ убедиться, что это правильный шестнадцатеричный номерзначение и возвращает шестнадцатеричное значение, если оно истинно, или возвращает сообщение об ошибке, если оно ложно.

Я думал о функции, которая проверяет каждый символ, чтобы убедиться, что он 0-9 или A-F, но не может думатькак это реализовать.

Спасибо.

Ответы [ 5 ]

19 голосов
/ 06 декабря 2011

Учитывая const char *s, если вы хотите определить, является ли каждый символ в строке, на которую указывает s, действительной шестнадцатеричной цифрой, которую вы можете использовать:

if (s[strspn(s, "0123456789abcdefABCDEF")] == 0)
{
    /* valid */
}
1 голос
/ 25 ноября 2017

Добавляя к ответу caf, используя его метод, эта функция работает для всех основ радикса от двоичного до base32. Вы можете легко проверить действительное число.

#define BINARY_BASE 2 /*Defining binary base*/
#define OCTAL_BASE 8  /*Defining octal base*/
#define DECIMAL_BASE 10 /*Defining decimal base*/
#define HEXA_BASE 16    /*Defining hexa-decimal base*/
#define BASE32_BASE 32 /*Defining base32 base*/

bool isValidNumber4Base(const char* numStr,int base)
{

    const char *validBinary = "01";
    const char *validOctal = "01234567";
    const char *validDecimal = "0123456789";
    const char *validHex = "0123456789abcdefxABCDEFX";
    const char *validBase32 = "0123456789abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUV";
    const char *validNumber = NULL;

    validNumber = (base == BINARY_BASE) ? validBinary : ((base == OCTAL_BASE) ? validOctal :
                    (base == DECIMAL_BASE) ? validDecimal : (base == HEXA_BASE) ? validHex : (base == BASE32_BASE) ? validBase32 : NULL);

    if(validNumber ==  NULL)
    {
        fputs("Invalid base encountered",stderr);
        exit(EXIT_FAILURE);
    }

    return (!numStr[strspn(numStr,validNumber)]) ? true : false;
}

/*Test Method For Hexa-deicmal */
int main ()
{
  char *hexa_str = "0x7FFF";    
  printf("Valid Hexa : %s\n",isValidNumber4Base(hexa_str,HEXA_BASE) == true ? "true" : "false");        
  return 0;
}
1 голос
/ 06 декабря 2011

Это должно сделать работу

int validate_hex(const char* hex){
  while(*hex != 0){
    if(*hex < '0' || *hex > '9')
      return 0;
    if(*hex < 'A' || *hex > 'F')
      return 0;
    hex++;
  }
  return 1;
}
0 голосов
/ 06 декабря 2011

Так же, как и в strtod, в стандартной библиотеке C strtoul есть возможность преобразования текста в unsigned long.

Опираясь на пример из вашего предыдущего вопроса:

#include <errno.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

  unsigned int intValue;
  char *e,s[100];

  fgets(s,100,stdin); if( s[strlen(s)-1]=='\n' ) s[strlen(s)-1]=0;
  errno=0;
  intValue= strtoul(s,&e,16);
  if( *e || errno==EINVAL || errno==ERANGE )
    puts("error");    
  else
    printf("intValue=0x%04x\n", intValue);

Если вы не укажете базу, она может читать в виде обычного целого, шестнадцатеричного, если с префиксом 0x, и восьмеричногоесли у вас есть ведущий ноль (но большинство людей об этом забывают, и я столкнулся с проблемами, когда люди ставили лидирующие нули для форматирования, а это испортило преобразования)

0 голосов
/ 06 декабря 2011

Примерно так (так как вы настаиваете, что это не домашняя работа, я заполню):

int CheckMyString(const char *aStr)
{
    const char *curr = aStr;
    while (*curr != 0)
    {
        if (('A' <= *curr && *curr <= 'F') || ('a' <= *curr && *curr <= 'f') || '0' <= *curr && *curr <= '9'))
        {
            ++curr;
        } 
        else 
        {
            return 0;
        }
    }
    return 1;
}
...