如何用scanf()循环读取十六进制值并检测换行符终止输入?
问题分析与解决方案
你的代码存在两个关键问题,导致输入少于5个值时无法终止:
scanf("%x", &curr_hex)会自动跳过所有空白字符(空格、换行、制表符等),因此永远无法通过curr_hex == '\n'检测到换行——换行被scanf直接忽略了。curr_hex在第一次循环判断时未初始化,属于未定义行为,可能导致程序逻辑混乱。
方法1:结合getchar()处理输入流
在每次读取十六进制值后,手动检查后续字符是否为换行,同时跳过多余空格:
#include <stdio.h> #define MAX_CHAR_LENGTH 5 int main() { unsigned int curr_hex; int ch; printf("enter hex values: "); for (int i = 0; i < MAX_CHAR_LENGTH; i++) { // 尝试读取十六进制值,失败则检查是否为换行 if (scanf("%x", &curr_hex) != 1) { ch = getchar(); if (ch == '\n' || ch == EOF) { break; } continue; } printf("Read hex: 0x%02X\n", curr_hex); // 跳过后续空格,检查是否到换行 while ((ch = getchar()) == ' ') { continue; } if (ch == '\n' || ch == EOF) { break; } // 将非空格非换行的字符放回输入流,供下一次读取 ungetc(ch, stdin); } return 0; }
方法2:用fgets()读取整行后解析
先读取整行输入,再从字符串中逐段解析十六进制值,这种方式更健壮,避免输入流混乱:
#include <stdio.h> #include <ctype.h> #define MAX_CHAR_LENGTH 5 #define BUFFER_SIZE 100 int main() { unsigned int curr_hex; char buffer[BUFFER_SIZE]; char *ptr; printf("enter hex values: "); if (fgets(buffer, BUFFER_SIZE, stdin) == NULL) { return 1; } ptr = buffer; for (int i = 0; i < MAX_CHAR_LENGTH; i++) { // 从当前指针位置解析十六进制 if (sscanf(ptr, "%x", &curr_hex) != 1) { break; } printf("Read hex: 0x%02X\n", curr_hex); // 跳过当前十六进制后的空白字符 while (*ptr != '\0' && isspace((unsigned char)*ptr)) { ptr++; } // 跳过当前十六进制的数字字符 while (*ptr != '\0' && isxdigit((unsigned char)*ptr)) { ptr++; } // 遇到换行或行尾则终止 if (*ptr == '\n' || *ptr == '\0') { break; } } return 0; }
核心要点
%x格式符会自动跳过空白,所以不能直接通过读取到的值判断换行,必须额外处理输入流或整行读取。- 两种方法都能实现“读取至5个值或遇到换行终止”的需求,第二种方法更适合处理复杂输入场景。
内容的提问来源于stack exchange,提问作者user27217858
相关产品推荐
相关产品推荐

