厂商提供的代码在Pelles C编译时出现“EOF in inline file”错误,如何解决?
分析与修复:Pelles C编译"EOF in file"错误及CRC程序问题
看起来你这段代码有不少语法和逻辑问题,正是这些问题导致编译器解析时出现"EOF in file"错误(通常是因为语法错误让编译器无法正确解析到文件结尾),同时也没法实现你想要的CRC输出功能。咱们一步步来拆解问题和修复:
主要错误点分析
- 错误的类型声明:
str scan = "";里的str不是C语言的内置类型,你需要用char数组来存储输入字符串,而且不能直接给未初始化的数组赋值字符串字面量,得先声明足够大小的数组。 - 函数名不匹配:你在
main里调用的是calc_crc_half,但实际定义的函数是cal_crc_half(少了一个c),这会导致编译器找不到函数定义,触发编译错误。 - 缺失头文件与类型定义:
INT16U、INT8U这些是自定义的整数类型,要么自己用typedef定义,要么用标准库的uint16_t/uint8_t(需要包含stdint.h);另外printf、fgets这些函数需要包含stdio.h才能使用。 - 过时的
far关键字:far是16位DOS程序里的内存模型关键字,在Windows 10 x64环境下完全不需要,直接去掉即可,否则会引发编译错误。 - 错误的
printf用法:printf(crc);没有指定格式字符串,这不仅会输出乱码,还可能导致程序崩溃。你需要用格式符来输出4位十六进制的CRC值,比如%04X。 - 函数原型缺失:在
main调用CRC函数之前没有声明函数原型,编译器会默认它返回int类型,和实际的16位无符号整数返回值不匹配,会引发警告或错误。 - 逻辑问题:你调用
calc_crc_half(scan, 4);时固定传了长度4,但输入的字符串长度可能不是4,应该先获取实际输入的有效长度(还要去掉fgets读取的换行符)。
修复后的完整代码
#include <stdio.h> #include <stdint.h> #include <string.h> // 先声明函数原型 uint16_t calc_crc_half(uint8_t *pin, uint8_t len); int main(){ // 声明足够大小的字符数组存储输入,初始化全0 char scan[100] = {0}; printf("Enter String: "); // 读取输入字符串,最多99个字符(留一个给终止符) fgets(scan, sizeof(scan), stdin); // 去掉fgets读取的换行符(如果存在) size_t input_len = strlen(scan); if (input_len > 0 && scan[input_len - 1] == '\n') { scan[input_len - 1] = '\0'; input_len--; } // 如果输入为空,提示用户 if (input_len == 0) { printf("Empty input!\n"); return 1; } // 调用CRC计算函数,传入实际输入长度 uint16_t crc_result = calc_crc_half((uint8_t*)scan, (uint8_t)input_len); // 输出4位十六进制字符串,补前导0 printf("CRC Result: %04X\n", crc_result); return 0; } uint16_t calc_crc_half(uint8_t *pin, uint8_t len){ uint16_t crc; uint8_t da; uint8_t *ptr; uint8_t bCRCHigh; uint8_t bCRCLow; const uint16_t crc_ta[16] = { 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef }; ptr = pin; crc = 0; while(len-- != 0) { da = ((uint8_t)(crc >> 8)) >> 4; crc <<= 4; crc ^= crc_ta[da ^ (*ptr >> 4)]; da = ((uint8_t)(crc >> 8)) >> 4; crc <<= 4; crc ^= crc_ta[da ^ (*ptr & 0x0f)]; ptr++; } bCRCLow = crc; bCRCHigh = (uint8_t)(crc >> 8); // 规避特定字符的逻辑保留 if(bCRCLow == 0x28 || bCRCLow == 0x0d || bCRCLow == 0x0a){ bCRCLow++; } if(bCRCHigh == 0x28 || bCRCHigh == 0x0d || bCRCHigh == 0x0a){ bCRCHigh++; } crc = ((uint16_t)bCRCHigh) << 8; crc += bCRCLow; return crc; }
修复说明
- 替换了自定义类型为标准库的
uint16_t/uint8_t,确保跨平台兼容性,同时包含了必要的头文件。 - 修正了函数名不匹配的问题,统一为
calc_crc_half。 - 去掉了过时的
far关键字,适配Win64环境。 - 修复了
printf的用法,用%04X输出4位十六进制字符串,符合你的预期。 - 处理了
fgets读取的换行符,确保传入CRC函数的是有效字符串长度。 - 添加了函数原型,避免编译器的隐式声明警告。
- 优化了输入数组的大小,避免潜在的越界问题。
现在用Pelles C编译这段代码应该就能正常运行了,输入字符串后会输出4位的CRC十六进制值。
内容的提问来源于stack exchange,提问作者Tim Yorba
相关产品推荐
相关产品推荐

