C语言:从文件读取十六进制值填充数组的fgets使用问题求助
问题分析与解决方案
咱们先拆解你遇到的错误,再聊聊能不能用fgets实现你的需求——答案是可以,但得先修正代码里的类型错误,再调整逻辑。
首先,你收到的报错passing argument 1 of 'fgets' makes pointer from integer without a cast,原因很明确:
你的decryptHexArray是int*类型,decryptHexArray[counter]取出来的是一个int值,但fgets的第一个参数要求是字符指针(char*),用来存储读取到的字符串。直接把int塞进去,编译器当然会报错,这是典型的类型不匹配问题。
接下来给你两种实用的方案,适配不同的文件格式:
方案1:用fgets逐行读取后解析十六进制值
如果你的output.txt里每个十六进制值单独占一行(比如每行是A3、0F这样的两位字符串),这个方案最适合:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *decryptIn = fopen("output.txt", "r"); if (!decryptIn) { // 一定要检查文件是否打开成功,别忽略这个! perror("Failed to open output.txt"); return 1; } // 先分配初始内存,后续不够再扩容(比用文件大小估算更稳妥) int *decryptHexArray = malloc(sizeof(int) * 1024); if (!decryptHexArray) { perror("Malloc failed to allocate memory"); fclose(decryptIn); return 1; } char lineBuffer[10]; // 存每行的十六进制字符串,两位足够,留余量防换行 int counter = 0; while (fgets(lineBuffer, sizeof(lineBuffer), decryptIn)) { // 先去掉换行符(fgets会把换行也读进来) lineBuffer[strcspn(lineBuffer, "\n")] = '\0'; // 把十六进制字符串转成整数 int hexValue; if (sscanf(lineBuffer, "%x", &hexValue) == 1) { decryptHexArray[counter++] = hexValue; // 内存不够时自动扩容 if (counter % 1024 == 0) { int *tempPtr = realloc(decryptHexArray, sizeof(int)*(counter + 1024)); if (!tempPtr) { perror("Realloc failed to expand memory"); free(decryptHexArray); fclose(decryptIn); return 1; } decryptHexArray = tempPtr; } } } // 到这里,decryptHexArray里就存了所有解密需要的十六进制整数值 // 这里可以加你的解密逻辑... // 记得释放内存和关闭文件! free(decryptHexArray); fclose(decryptIn); return 0; }
方案2:直接逐字符解析(适合连续无分隔的十六进制字符串)
如果你的文件里十六进制值是连续的(比如A30F12这样没有换行或空格分隔),用fgetc逐字符读取解析会更灵活,当然也可以结合fgets读取大段后再处理,但逐字符更直接:
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main() { FILE *decryptIn = fopen("output.txt", "r"); if (!decryptIn) { perror("Failed to open output.txt"); return 1; } int *decryptHexArray = malloc(sizeof(int) * 1024); if (!decryptHexArray) { perror("Malloc failed"); fclose(decryptIn); return 1; } int counter = 0; int char1, char2; while ((char1 = fgetc(decryptIn)) != EOF) { // 跳过空白字符(空格、换行、制表符都算) while (isspace(char1) && char1 != EOF) { char1 = fgetc(decryptIn); } if (char1 == EOF) break; char2 = fgetc(decryptIn); // 同样跳过第二个字符的空白 while (isspace(char2) && char2 != EOF) { char2 = fgetc(decryptIn); } if (char2 == EOF) break; // 把两个字符转换成十六进制整数 int hexValue = 0; // 处理第一个字符(左移4位,占高4位) if (isdigit(char1)) { hexValue = (char1 - '0') << 4; } else if (toupper(char1) >= 'A' && toupper(char1) <= 'F') { hexValue = (toupper(char1) - 'A' + 10) << 4; } // 处理第二个字符(占低4位) if (isdigit(char2)) { hexValue += (char2 - '0'); } else if (toupper(char2) >= 'A' && toupper(char2) <= 'F') { hexValue += (toupper(char2) - 'A' + 10); } decryptHexArray[counter++] = hexValue; // 内存扩容逻辑 if (counter % 1024 == 0) { int *tempPtr = realloc(decryptHexArray, sizeof(int)*(counter + 1024)); if (!tempPtr) { perror("Realloc failed"); free(decryptHexArray); fclose(decryptIn); return 1; } decryptHexArray = tempPtr; } } // 解密逻辑... free(decryptHexArray); fclose(decryptIn); return 0; }
几个关键提醒
- 永远检查文件和内存操作结果:文件可能打不开,内存可能分配失败,这些都要处理,不然程序容易崩溃。
- 别用文件字节数直接算数组大小:原代码里用
fseek和ftell获取的是字节数,但文本文件里每个十六进制值可能带换行或空格,字节数和值的数量不成正比,动态扩容更靠谱。 - 根据文件格式选方案:先确认你的
output.txt里十六进制值是怎么分隔的,再选对应的解析方式,效率更高。
内容的提问来源于stack exchange,提问作者joefthdfthfth
相关产品推荐
相关产品推荐

