C,sprintf和string和int的“sum”

时间:2010-07-08 09:58:57

标签: c printf

我很多时候没有使用过C,现在我必须修改一小段代码。有一点我无法理解:

char filename[20];
filename[0] = '\0';
for (j=0; j < SHA_DIGEST_LENGTH; j++){
  sprintf(filename + strlen(filename),"%02x",result[j]);
}

在第一行中,将显示一个包含20个字符的字符串。 在第二行中,第一个字符设置为'\ 0',我想是一个空字符串。

在for循环中我不明白文件名和它的长度之间的“总和”...... sprintf的第一个参数应该是一个缓冲区,在那里复制右边的格式化字符串。这笔款项的结果是什么?在我看来,我正在尝试将数组和整数相加...

我缺少什么?

5 个答案:

答案 0 :(得分:13)

它是指针算术。 strlen返回NUL终结符之前的字符数。添加的结果将指向此终结符。例如。如果当前字符串是“AA”(后跟NUL),则strlen为2. filename + 2指向NUL。它将在NUL和下一个字符上写下一个十六进制字符(例如BB)。然后它将再次终止它(在filename + 4)。那么你将拥有“AABB”(然后是NUL)。

但它确实没有意义。它浪费了很多时间寻找那些NUL。具体来说,它是一个二次算法。第一次,它检查1个字符,然后3,5,7,...,2 * SHA_DIGEST_LENGTH - 1)那个。它可能只是:

sprintf(filename + 2 * j,"%02x",result[j]);

还有另一个问题。 SHA-1和的十六进制表示需要40个字符,因为一个字节需要两个字符。然后,你有一个最终的NUL终结符,所以应该有41.否则,就会出现缓冲区溢出。

答案 1 :(得分:1)

第一次迭代,当j = 0时,您将写入3个字符(是的,包括终止字符串的'\0')到filename的开头,因为strlen()然后返回0。 下一轮,strlen()返回2,它将在前两个字符后继续写入。

小心踩到分配的20个字符空间。常见的错误是忘记字符串终止符所需的空间。

编辑:确保SHA_DIGEST_LENGTH不大于9.

答案 2 :(得分:1)

为什么不宣布

char filename[SHA_DIGEST_LEN*2 +1]; / *如果你想让NULL终止char * /

,那就+1

这是因为SHA1摘要长度为20个字节,如果您只是打印摘要,那么您可能不需要额外的内存,但由于您需要摘要的十六进制字符串,您可以使用上述声明。 strlen操作返回字符串的长度,直到遇到空终止字符。

所以基本上当你执行以下操作时:

sprintf(filename + strlen(filename),"%02x",result[j]);

在第一次交互中,使用sha-1摘要的第一个字节的十六进制表示的2个字节复制filname。例如。假设这是AA,现在你需要将指针移动两个位置以复制下一个字节。

第二次迭代后,它变成了AABB。 在第20次迭代之后,你有整个字符串AABBCC ...... AA [40字节]和+1,如果你需要'\ 0'这是NULL终止字符。

答案 3 :(得分:0)

您只是添加strlen(filename)来进行result [j]

的连接

每次迭代都会在文件名末尾连接当前结果[j],这样每次你需要知道在连接应该发生的文件名中的偏移量。

答案 4 :(得分:0)

将代码替换为:

char filename[SHA_DIGEST_LENGTH*2+1];
for (j=0; j < SHA_DIGEST_LENGTH; j++){
  sprintf(filename + 2*j,"%02x",result[j]);
}

更快,更简单,错误消失了。

相关问题