如何添加仅允许a-f ||之间的字母的“(if)” A-F?

时间:2019-04-27 12:07:37

标签: c char hex decimal scanf

我写了一个程序,可以进行十六进制到十进制的转换。我剩下的只是检查char是否在a-fA-F之间,也许是0-{{1 }}。如果不在它们之间,则会打印9

我的代码:

"Illegal input"

我需要的输出:

Enter the number of digits in the Hexadecimal number: 2
Enter the Hexadecimal number: QQ
Illegal input

4 个答案:

答案 0 :(得分:2)

代码有几个问题。

对于初学者来说,功能scanf_s应包括格式说明符c的缓冲区大小作为参数。

要输出unsigned long类型的对象,必须使用格式说明符ul

在这些if语句中,您不检查有效的alpha十六进制数字的上限。

if (currentDigit >= 'a') {
    currentDigitInt = (currentDigit - 'a') + 10;
}
else if (currentDigit >= 'A') {
    currentDigitInt = (currentDigit - 'A') + 10;
}

要检查输入的符号是否为有效的十六进制数字,应编写一个单独的函数。

这里是一个演示程序,显示了如何完成此操作。

//Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64

#include  <stdio.h>
#include <string.h>
#include <ctype.h>

int hex_digit( char c )
{
    const char *alpha = "ABCDEF";

    unsigned char c1 = toupper( ( unsigned char )c );
    const char *p;

    int result = -1;

    if ( '0' <= c1 && c1 <= '9' )
    {
        result = c1 - '0';
    }
    else if ( c1 != '\0' && ( p = strchr( alpha, c1 ) ) != NULL )
    {
        result = *p - alpha[0] + 10;
    }
    return result;
}

int main(void)
{
    const unsigned long HEX_BASE = 16;
    unsigned int n;

    printf( "Enter the number of digits in the Hexadecimal number: " );
    scanf_s("%u", &n); 

    unsigned long sum = 0;

    if ( n )
    {            
        printf( "Enter the Hexadecimal number: " );

        unsigned int i = 0;
        for ( ; i < n; i++ )
        {
            char c;

            scanf_s( " %c", &c, 1 );

            int digit = hex_digit( c );

            if ( digit < 0 ) break;
            else sum = sum * HEX_BASE + digit; 
        }

        if ( i == n )
        {
            printf("The decimal number is: %ul\n", sum);
        }
        else
        {
            puts( "Illegal input" );
        }    
    }

    return 0;
}

其输出可能如下所示

Enter the number of digits in the Hexadecimal number: 8
Enter the Hexadecimal number: ffFFffFF
The decimal number is: 4294967295l

如果需要,可以在程序中添加一个检查,以确保输入的十六进制数字的指定数量不大于2 * sizeof( unsigned long )

答案 1 :(得分:0)

aA)到fF)在C中不必连续。

如果您希望程序在C的所有实现上运行(klingon太空飞船,DS9K,火星漫游者,...,...),则可以尝试这样的操作

if ((currentdigit == 0) || (strchr("0123456789abcdefABCDEF", currentdigit) == NULL)) /* invalid */;

答案 2 :(得分:0)

您的代码中存在多个问题:

  • 您可以使用&&运算符测试字符范围。例如:

    if (currentDigit >= 'a' && currentDigit <= 'f')
    
  • 您将这些测试合并为一系列if / else,并在没有一个匹配的情况下抱怨。

  • 还要注意sum的表达式也不正确。 sum += currentDigitInt * pow(16, i);应该是

    sum = sum * 16 + currentDigitInt;
    
  • printf的{​​{1}}格式是unsigned long,而不是%lu

  • 您应该测试%u的返回值以正确检测文件的潜在结尾。

  • scanf_s期望为转换说明符scanf_s增加2个参数,并且可能并非在所有系统上都可用。

  • 也请注意,您不需要输入十六进制数字,只需在输入的字符第二次是换行符时从循环中中断即可。

这是更正的版本:

%c

注意:

  • C标准确实保证#include <stdio.h> int main() { int currentDigit; unsigned long int sum; int invalid = 0; printf("Enter the Hexadecimal number: "); sum = 0; while ((currentDigit = getchar()) ! EOF && currentDigit != '\n') { int currentDigitInt; if (currentDigit >= 'a' && currentDigit <= 'f') { currentDigitInt = (currentDigit - 'a') + 10; } else if (currentDigit >= 'A' && currentDigit <= 'F') { currentDigitInt = (currentDigit - 'A') + 10; } else if (currentDigit >= '0' && currentDigit <= '9') { currentDigitInt = currentDigit - '0'; } else { invalid = 1; continue; // keep scanning the input until end of line } sum = sum * 16 + currentDigitInt; } if (invalid) { printf("Invalid input\n"); } else { printf("The decimal number is: %lu\n", sum); } return 0; } 0是连续的,但纯粹主义者会争辩9af至{{1 }}可能不连续执行字符集。虽然正确,但由于这些考虑而使新手程序员望而却步,反而会适得其反,而且因为这些字符范围在ASCII和EBCDIC中都是连续的(EBCDIC中的间距介于AF之间以及{{ 1}}和i)。

答案 3 :(得分:-1)

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int isaTof(int c)
{
    c = toupper(c);

    if(c >= 'A' && c <= 'F') return 1;
    return 0;
}


int isin(int c, const char *allowedchars)
{
    return strchr(allowedchars, c) != NULL;
}

int isHEXNumber(const char *number)
{
    const char allowedchars[] = "abcdefABCDEF0123456789";
    while(*number)
    {
        if(!isin(*number++, allowedchars)) return 0;
    }
    return 1;
}

或nitpickers版本

int isHEXNumber(const char *number)
{
    const char allowedchars[] = "abcdefABCDEF0123456789";

    if(!number || |*number) return 0;
    while(*number)
    {
        if(!isin(*number++, allowedchars)) return 0;
    }
    return 1;
}



int main()
{
    const char allowedchars[] = "abcdefABCDEF0123456789";

    printf("%s\n", isin('d', allowedchars) ? "Yes" : "No");

    return 0;
}