我写了一个程序,它从十六进制转换为十进制。我剩下的就是检查char
是否在a
-f
或A
-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", ¤tDigit);
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
您的代码中存在多个问题:
&&
运算符测试字符范围。例如:
if (currentDigit >= 'a' && currentDigit <= 'f')
if
/ else
中,如果没有一个测试匹配,就会抱怨。sum
的表达式也是错误的。 sum += currentDigitInt * pow(16, i);
应该是;
sum = sum * 16 + currentDigitInt;
printf
的unsigned 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;
}
笔记:
0
通过9
是连续的,但纯粹主义者会争辩说a
通过f
和A
通过F
可能不是连续的执行字符集。虽然这是正确的,但是这些考虑因素模糊新手程序员会产生相反的效果并且相当过分,因为这些字符范围在ASCII和EBCDIC中都是连续的(EBCDIC中的差距在i
和j
之间以及在两种情况下在r
和s
之间)。代码有几个问题。
对于初学者,函数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。
2 * sizeof( unsigned long )
(a
)到A
(f
)不需要在C中连续。
如果你想让你的程序在C(klingon space-ship,F
,Mars Rover,......,......)的所有实现上运行,你可以试试这样的东西
DS9K
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;
}