解析十六进制字符文件并存储到缓冲区时陷入死循环问题排查
问题分析与修复方案
核心死循环原因:运算符优先级错误
代码中两个while循环的条件存在优先级逻辑错误:
while (c1 = fgetc(file) != '\n' && c1 != EOF)
!=运算符的优先级高于=,导致实际执行顺序是先判断fgetc(file) != '\n',将得到的布尔值(0或1)赋值给c1。由于c1永远不会等于EOF(值为-1),循环无法终止,陷入死循环。
修复步骤
1. 修正循环条件的运算符优先级
给赋值操作加上括号,确保先完成字符读取赋值,再进行判断:
while ((c1 = fgetc(file)) != '\n' && c1 != EOF)
两个while循环都需要做此修改。
2. 处理c2的EOF边界情况
读取c2后需检查是否为EOF,避免后续处理无效字符:
while ((c1 = fgetc(file)) != '\n' && c1 != EOF) { c2 = fgetc(file); if (c2 == EOF) break; // 提前终止,避免处理无效字符 byte[0] = c1; byte[1] = c2; (*buf)[pos++] = hexadecimal_to_int(byte); }
3. 修正变量类型溢出问题
main函数中buf_size的类型是uint8_t,但read_file返回的size是uint32_t,当文件内容超过255字节时会溢出,应修改为:
uint32_t buf_size = read_file(fp, &buffer);
4. 优化十六进制转换逻辑(可选)
hexadecimal_to_int函数设计为处理任意长度十六进制字符串,但此处仅需处理2个字符,可简化逻辑提升效率:
static uint8_t hex_char_to_byte(char c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'a' && c <= 'f') return c - 'a' + 10; else if (c >= 'A' && c <= 'F') return c - 'A' + 10; return 0; // 非法字符处理,可按需调整 } // 在read_file中替换原hexadecimal_to_int调用: (*buf)[pos++] = (hex_char_to_byte(c1) << 4) | hex_char_to_byte(c2);
5. 使用二进制模式打开文件(可选)
Windows系统下,文本模式("r")会将\r\n转换为\n,可能导致读取字符数不符,建议用二进制模式打开:
FILE *fp = fopen(argv[1], "rb");
修复后的完整read_file函数
uint32_t read_file(FILE *file, uint8_t **buf) { uint32_t size = 0; char c1; char c2; int64_t startpos = ftell(file); // 修正第一个循环的条件优先级 while ((c1 = fgetc(file)) != '\n' && c1 != EOF) { c2 = fgetc(file); if (c2 == EOF) break; ++size; } *buf = (uint8_t *)malloc(size); if (*buf == NULL) { fprintf(stderr, "Malloc failed!\n"); return 0; } fseek(file, startpos, SEEK_SET); int32_t pos = 0; // 修正第二个循环的条件优先级,增加c2检查 while ((c1 = fgetc(file)) != '\n' && c1 != EOF) { c2 = fgetc(file); if (c2 == EOF) break; (*buf)[pos++] = (hex_char_to_byte(c1) << 4) | hex_char_to_byte(c2); } return size; }
内容的提问来源于stack exchange,提问作者Iberico
相关产品推荐
相关产品推荐

