使用sprintf和strcat转换哈希时的字符串异常问题求助
问题分析与解决方案
嘿,这个问题我太熟悉了!咱们来一步步拆解:
核心问题出在两个地方:
- 未初始化的
hash数组缺少字符串终止符 hash数组的空间不足以容纳字符串终止符,引发未定义行为
先解释第一个问题:你声明的unsigned char hash[8][32];是未初始化的数组,内存里的初始值是随机的。而strcat的工作逻辑是从目标字符串的末尾'\0'开始追加内容——如果目标字符串没有'\0',它会一直往内存深处找,直到碰巧遇到一个,这就会越界覆盖后面的hash[4]、hash[5]等空间。
循环内输出看似正常,是因为你刚追加完32个字符后,碰巧在当前hash[k]的末尾附近有个随机的'\0';但循环结束后,后续的循环已经把后面的空间都写满了数据,没有了那个碰巧的终止符,所以printf(hash[3])会一直输出直到遇到内存里某个遥远的'\0',就把后面所有哈希内容都带上了。
第二个隐藏问题:C语言的字符串必须以'\0'结尾,32个字符的哈希字符串需要33个字节的空间(32个字符+1个终止符)。你现在的hash[8][32]刚好只能放下32个字符,没有空间放'\0',这本身就是未定义行为,随时可能出问题。
修复方案(按推荐程度排序)
方案1:初始化数组+调整空间大小(最稳妥)
直接把hash数组初始化为全0,同时调整大小为33字节,确保每个子数组一开始就有'\0',且能容纳终止符:
// 全部初始化为0,每个子数组的第一个字节就是'\0',空间足够放32字符+终止符 unsigned char hash[8][33] = {0}; unsigned char hashResults[8][16]; unsigned char tmp[3]; // 改成3,因为%02x会输出2个字符+'\0',避免溢出 transformation("toto", 4, hashResults); for (int k = 0; k < 8; ++k) { for (int i = 0; i < 16; ++i) { sprintf(tmp,"%02x",hashResults[k][i]); strcat(hash[k],tmp); } printf("%zu \n%s\n", strlen(hash[k]), hash[k]); // 用%zu对应size_t类型的strlen返回值 } printf("Test : %s\n", hash[3]);
方案2:直接定位写入,避免strcat(更高效)
其实完全不需要用strcat,我们可以直接计算每个字符的位置,用sprintf直接写入,既高效又能避免终止符问题:
unsigned char hash[8][33] = {0}; unsigned char hashResults[8][16]; transformation("toto", 4, hashResults); for (int k = 0; k < 8; ++k) { for (int i = 0; i < 16; ++i) { // 每个字节对应2个字符,偏移量是i*2 sprintf(&hash[k][i*2], "%02x", hashResults[k][i]); } printf("%zu \n%s\n", strlen(hash[k]), hash[k]); } printf("Test : %s\n", hash[3]);
方案3:手动初始化每个子数组(应急修复)
如果不想改数组大小(不推荐,因为还是有空间隐患),可以在每次处理hash[k]前手动设置终止符:
unsigned char hash[8][32]; unsigned char hashResults[8][16]; unsigned char tmp[3]; transformation("toto", 4, hashResults); for (int k = 0; k < 8; ++k) { hash[k][0] = '\0'; // 手动把当前子数组初始化为空字符串 for (int i = 0; i < 16; ++i) { sprintf(tmp,"%02x",hashResults[k][i]); strcat(hash[k],tmp); } // 注意:这里strlen返回32是因为刚好没有越界到终止符,但数组已经满了,属于未定义行为 printf("%zu \n%s\n", strlen(hash[k]), hash[k]); }
额外提醒
- 用
%02x代替%2.2x,效果是一样的,但更符合C语言格式化字符串的常规写法 strlen的返回值是size_t类型,输出时应该用%zu而不是%d,避免类型不匹配的警告
内容的提问来源于stack exchange,提问作者user9772676
相关产品推荐
相关产品推荐

