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] == '\0') {
printf("Success :%08x\n", number);
} else {
fprintf(stderr, "please insert a valid number\n");
}
}
如果代码需要确保文本不包含 "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] == '\0') {
unsigned long number = strtoul(buf, NULL, 16);
printf("Success :%08lx\n", number);
} else {
fprintf(stderr, "please insert a valid number\n");
}
}
一个聪明的方法是避免*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 number\n");
} else {
printf("Success :%08lx\n", number);
}
}