【问题标题】:Inputing & validating hex values correctly正确输入和验证十六进制值
【发布时间】:2012-01-13 16:04:52
【问题描述】:

我正在尝试创建一个简单的程序或函数来接受用户输入,这可能是一个有效的十六进制数字。

我正在尝试找出一种方法来验证它是否是正确的十六进制值,如果为真则返回十六进制值,如果为假则返回错误消息。

我正在考虑一个检查每个字符以确保其 0-9A-F 的函数,但不知道如何实现。

谢谢。

【问题讨论】:

  • 这是作业吗?如果是,请添加作业标签。
  • 不是作业,我正在尝试建立我的 C 知识,发现它非常困难,因为在线教程不是很好,而且我确实有一个基本功能来验证输入然后丢失了我的所有数据usb,我似乎无法让它完全验证十六进制
  • 嗯.. 从更简单的程序开始。确保你能理解 ifwhile 和朋友,然后才能继续前进。
  • 知道了,我从基本程序开始,并设法建立了一个复杂的程序,输入数据比较、验证和错误处理等

标签: c validation input hex


【解决方案1】:

使用他的方法添加到 caf 的答案中,此函数适用于从 binary 到 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;
}

【讨论】:

    【解决方案2】:

    这样的(因为你坚持不是作业,我会填写):

    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;
    }
    

    【讨论】:

    • 我喜欢这段代码,它为一个十六进制验证它让我失望,如果你验证一个字符串 AZ 它会起作用,但是验证 ust 0-9 AF 似乎被证明是困难的
    • 我也同意 Beginner 的观点,这一定是 C++ 通过注释样式猜测的,以及 C 一般用途 /* */
    【解决方案3】:

    就像 strtod 一样,标准 C 库中有 strtoul 用于将文本转换为无符号长整数。

    以您上一个问题中的示例为基础:

    #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 为前缀,它可以读取十六进制,如果你有一个前导零,它也可以读取八进制(但大多数人忘记了这一点,我遇到了人们的问题已经为格式化输入了前导零并且它搞砸了转换)

    【讨论】:

      【解决方案4】:

      给定const char *s,如果您想确定s 指向的字符串中的每个字符是否都是有效的十六进制数字,您可以使用:

      if (s[strspn(s, "0123456789abcdefABCDEF")] == 0)
      {
          /* valid */
      }
      

      【讨论】:

      • 如果非空字符串中的每个字符。
      • @pmor:如果字符串为空,则字符串中的字符集是空集,关于它的元素的每个命题都是空的!
      • 非常感谢!这是我很难理解的:为什么它是“(空洞的)真相”而不是“未知”?如果房间里没有手机,那么如果没有前件(即手机),我们如何推断房间里的所有手机是关闭还是打开?我最近遇到的另一个例子:如果测试没有执行,那么它的状态是什么:通过还是失败?我得出的结论是它的状态应该是“未知的”。这是否意味着根据空洞的真理,它的地位将被通过?你能对此发表评论吗?
      • @pmor:这个问题的答案可能会有所帮助:math.stackexchange.com/questions/50873/…。数理逻辑没有“未知”,因为这是关于我们对命题的知识的陈述,而不是关于命题本身的真实性的陈述。
      【解决方案5】:

      这应该可以完成工作

      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;
      }
      

      【讨论】:

      • 如果您要逐个字符地比较它,那么您不妨使用 isxdigit() 内置函数。
      • 这看起来会失败。如果字符是“A”,第一个测试将确定它大于“9”并错误地返回 false。
      猜你喜欢
      • 2021-11-27
      • 2018-09-07
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      • 1970-01-01
      • 2016-11-15
      • 2017-06-08
      • 1970-01-01
      相关资源
      最近更新 更多