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

问题描述 投票:-1回答:4

我写了一个程序,它从十六进制转换为十进制。我剩下的就是检查char是否在a-fA-F之间,也许是0-9。如果它们之间没有它将打印"Illegal input"

我的代码:

int n, i;
char currentDigit;
unsigned long int sum, currentDigitInt;

printf("Enter the number of digits in the Hexadecimal number:");
scanf_s("%d", &n);
sum = 0;

printf("Enter the Hexadecimal number:\n");
for (i = n - 1; i >= 0; i--) {
    scanf_s(" %c", &currentDigit);

    if (currentDigit >= 'a') {
        currentDigitInt = (currentDigit - 'a') + 10;
    }
    else if (currentDigit >= 'A') {
        currentDigitInt = (currentDigit - 'A') + 10;
    }
    else
        currentDigitInt = currentDigit - '0';
    sum += currentDigitInt * pow(16, i);
}

printf("The decimal number is: %u", sum);

我需要的输出:

Enter the number of digits in the Hexadecimal number: 2
Enter the Hexadecimal number: QQ
Illegal input
c char hex decimal scanf
4个回答
0
投票

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

  • 您可以使用&&运算符测试字符范围。例如: if (currentDigit >= 'a' && currentDigit <= 'f')
  • 你将这些测试结合在一系列if / else中,如果没有一个测试匹配,就会抱怨。
  • 另请注意,sum的表达式也是错误的。 sum += currentDigitInt * pow(16, i);应该是; sum = sum * 16 + currentDigitInt;
  • printfunsigned long格式是%lu,而不是%u
  • 你应该测试scanf_s的返回值,以正确检测文件的潜在结束。
  • scanf_s期望转换说明符%c有2个额外的参数,并且可能并非在所有系统上都可用。
  • 另请注意,您不需要询问十六进制数字的数量,只需在输入的字符第二次换行时从循环中断。

这是一个更正版本:

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

笔记:

  • C标准确保0通过9是连续的,但纯粹主义者会争辩说a通过fA通过F可能不是连续的执行字符集。虽然这是正确的,但是这些考虑因素模糊新手程序员会产生相反的效果并且相当过分,因为这些字符范围在ASCII和EBCDIC中都是连续的(EBCDIC中的差距在ij之间以及在两种情况下在rs之间)。

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

如果需要,可以在程序中添加一个检查,指定的输入十六进制数字的数量不大于qazxsw poi。


0
投票

2 * sizeof( unsigned long )a)到Af)不需要在C中连续。

如果你想让你的程序在C(klingon space-ship,F,Mars Rover,......,......)的所有实现上运行,你可以试试这样的东西

DS9K

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

或者是nitpickers版本

#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;
}
© www.soinside.com 2019 - 2024. All rights reserved.