我需要读取一个 C 中带有八位数字的十六进制数,我需要验证它。如果它少于八位,则用"0"填充。如果它超过八位数字,请打印一条消息,例如"请输入有效数字"。
我正在做这样的事情:
unsigned int number;
printf("nIntroduzca un número: ");
scanf("%08x", &number);
但是使用"%08x"我可以填写"0",但我不知道插入的数字是否超过八位并打印错误消息。
我想把它读成一个字符串,但后来我需要对它进行位运算并以十六进制和二进制打印结果,所以我不知道将数字读为字符串是否是个好主意。
如何解决这个问题?
scanf()
是用户输入的最佳选择。 最好使用 fgets()
读取一行,然后使用其他代码来分析字符串。
char buf[100];
while (fgets(buf, sizeof buf, stdin)) {
// code read the text input into a string, now do something with it.
代码正在寻找八个十六进制数字,OP 与 scanf("%08x"...
在正确的轨道上。 这里不需要0
,只需8
就可以将输入限制为 8 位数字。 使用 " "
跳过任何可选的空格。 使用 "%n"
记录解析的字符数。
unsigned number = 0;
int n = 0;
// If any length (up to 8) hex text was found ...
// ... and test if `buf[n]` is the end of the string or maybe that 9 digit?
if (sscanf(buf, "%8x %n", &number, &n) == 1) && buf[n] == ' ') {
printf("Success :%08xn", number);
} else {
fprintf(stderr, "please insert a valid numbern");
}
}
如果代码需要确保文本不包含类似"0x123"
的前导,则需要做更多的工作。 各种方法。
坚持使用*scanf()
说明符,使用 "%*[0123456789abcdefABCDEF]"
扫描字符串中的十六进制数字。 *
的意思是不保存,只是扫描。
int n = 0;
// If any length (up to 8) hex text was found ...
// ... and test if `buf[n]` is the end of the string or maybe that 9 digit?
sscanf(buf, "%*8[0123456789abcdefABCDEF] %n", &n);
if (n > 0 && buf[n] == ' ') {
unsigned long number = strtoul(buf, NULL, 16);
printf("Success :%08lxn", number);
} else {
fprintf(stderr, "please insert a valid numbern");
}
}
一个聪明的方法是避免一起*scanf()
,并在要解析的字符串前面附加一个"0x"
,并仅将strtol()
用于解析。
char buf[100];
while (fgets(&buf[2], sizeof buf - 2, stdin)) {
char *endptr;
buf[0] = '0';
buf[1] = 'x';
unsigned long number = strtoul(buf, &endptr, 16);
int length = (int) (endptr - buf);
if (length < 3 || length > (2 + 8) || *endptr != 'n') {
fprintf(stderr, "please insert a valid numbern");
} else {
printf("Success :%08lxn", number);
}
}
作为字符串读取。检查前 2 个字节,确保它们没有在开头添加 0x。使用strlen
验证长度。
然后,正如@Evert所说,使用 strtol
将其转换为十六进制值,使用基数 16。检查 strtol
的返回值以验证成功或失败 - 输入的十六进制数是否有效。