【问题标题】:strncpy behavior differs from sprintf'sstrncpy 行为与 sprintf 不同
【发布时间】:2012-11-18 11:19:20
【问题描述】:

我正在使用以下代码创建一个“密钥”以用于测试哈希表(特别是,我正在测试删除项目所需的时间):

void remove_keys()
{
    for (int i = 0; i < NUM_ITEMS; i++) {
        char temp_key[20];
        sprintf((char *)&temp_key, "Key: %d", i);
        size_t key_len = strlen(temp_key) + 1;


        char *key = malloc(sizeof(char) * (key_len));
        sprintf(key, "%s", temp_key); // THIS LINE

        htable_item *item = htable_item_search(root, key, key_len);
        if (!item) {
            printf("Item not found: %s\n", key);
        } else {
            //printf("Item found: %s - %s\n", key, item->value);
            if (!htable_item_delete(root, item)) {
                printf("Error while deleting: %s\n", key);
            }
        }
    }
}

在我用注释标记的行中有一个奇怪的行为。我正在使用 sprintf 将“temp_key”的内容复制到“key”。在此之前,我使用 strncpy 将“temp_key”的内容复制到“key”,但我从这个操作得到的结果是这样的(从 XCode 的调试器打印):

Printing description of key:
(char *) key = 0x0000000100103ed0 "Key: 10\xb0\xe7\x03\x01\x10"

而“temp_key”产生以下输出:

Printing description of temp_key:
(char [20]) temp_key = "Key: 10" {
  [0] = 'K'
  [1] = 'e'
  [2] = 'y'
  [3] = ':'
  [4] = ' '
  [5] = '1'
  [6] = '0'
  [7] = '\0'
  [8] = '\0'
  [9] = '\0'
  [10] = '\0'
  [11] = '\0'
  [12] = '\0'
  [13] = '\0'
  [14] = '\0'
  [15] = '\0'
  [16] = '\0'
  [17] = '\0'
  [18] = '\0'
  [19] = '\0'
}

哈希表使用 memcmp 来比较 htable_item_search 函数中的键。但是使用 strncpy 有一些项目(如“Key:10”)在使用 sprintf 时找不到它完美地工作。那么为什么会有这种差异呢?

【问题讨论】:

  • 你为什么不使用strdup。它与您的strlen+malloc+strcpy 完全一样,但只需一个简单的调用。它足够广泛,可以在任何情况下使用。
  • 而你的sprintf 是错误的:它应该是sprintf(temp_key, "Key: %d", i);。您必须进行类型转换以抑制警告,因为您使用了数组的 &。
  • 在 C 中,你的函数签名应该是void remove_keys(void)() 在 C 中意味着完全不同的东西。在 C++ 中可以,但在 C 中则不行。

标签: c printf strncpy


【解决方案1】:

来自http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

如果 source 长于 num,则不会在目标末尾隐式附加空字符(因此,在这种情况下,目标可能不是以空结尾的 C 字符串)。

strncpy 不会在字符串中添加空终止符,因此在使用此函数时,字符串末尾会有垃圾。

【讨论】:

  • 谢谢,我通过使用 strncpy 解决了,最后手动附加了一个空终止符。
  • 不客气!总是检查 c 引用,同时有任何来自 lib 方法的麻烦行为:函数背后有一个完整的世界^^
猜你喜欢
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
相关资源
最近更新 更多