【问题标题】:Comparing int8_t and char* using strcmp/strncmp使用 strcmp/strncmp 比较 int8_t 和 char*
【发布时间】:2019-01-30 16:01:07
【问题描述】:

目前正在尝试修复一段时间未使用的代码。

我有两个变量:int8_t foo[size]const char* const bar

有一个 if 检查 if(0 != strcmp((char *)foo, bar))

目前,即使printf("%s | %s", foo, bar) 返回两个完全相同的字符串,这也是失败的。我也试过strncmp,但也失败了。

通过在线研究,我知道这很可能是由于终止了空字节,但是我不知道如何解决/解决这个问题。

int8_t foo[size];
const char* const bar;

if(0 != strcmp((char *)foo, bar)){
   fail 
}

预期结果是 strcmp 返回 0,因为打印时两个字符串相同。

实际结果:返回失败。

实际数据:5352A565712345657567565785658956581
运行printf("Value of foo and bar: %s and %s", foo, bar) 时,两个变量都会返回上面的数据。

【问题讨论】:

  • 如果不知道这两个变量的确切数据是什么,我们就无法回答。
  • 如果你想要(字符串)字符,使用char。如果您想要小整数,请使用int8_tuint8_t(或signed charunsigned char)。
  • 按要求添加数据。
  • 不可打印的内容怎么办?你能确定没有吗?

标签: c pointers char strcmp strncmp


【解决方案1】:

拥有是不够的:

int8_t foo[] = { 'a', 'b' };

能够做到

if (strcmp(foo, "ab") == 0)
  puts("equals");
else
  puts("not equal");

因为 strcmp 像许多其他在 char * 上工作的函数一样,需要一个表示字符串结束的空字符。

strcmpfoo 中的 'b' 之后附加的内容是未定义的行为

所以

int8_t foo[] = { 'a', 'b', 0 };

strcmp(foo, "ab") 的候选对象,这要归功于添加的空字符允许 strcmp 在任何情况下都不会超出 foo


请注意,如果您在第一种情况下执行printf("%s", foo);,则会出现同样的问题,而在 foo 函数 printf 将尝试将内存写入字符,但这是未定义的行为

【讨论】:

  • 很好的答案,感谢您抽出宝贵的时间使其易于理解!只是一个快速的后续问题,foo,虽然初始化为 int8_t foo[size],但被传递给函数 x(foo)。此函数从 sqlite3 语句填充数组。在填充了它的值后,我如何将空终止符附加到 foo ?
  • 忽略上面的评论,我在数组后面附加了一个空终止符 0,但仍然无法正常工作。但是,当我将 foo 和 bar 打印为十六进制数字 (%x) 时,它们是不同的。 foo = vcd16a40 和 bar = vcd169e0
  • @CianO'Shaughnessy 函数 x 必须将空字节放在末尾,或者它必须返回设置的字节数,以便能够添加null 在正确的位置。然而混合字符串和字节数组是很奇怪的;-)
  • @CianO'Shaughnessy 你怎么能有 'v' 在 hexa ? int8_t foo[] = { 'a', 'b', 0 }; printf("%d\n", strcmp(foo, "ab")); 将打印 0
【解决方案2】:

尽管在编译时收到警告,但我无法重新创建此场景。 预期的行为是什么? 您的意思是比较失败,还是代码无法进入if 块? 如果两个数组包含相同的数据,strcmp() 将返回 0,然后if 块将不会被执行。

我只是想澄清一下。 bruno 的回答考虑到 strcmp 的行为也是正确的。

【讨论】:

    猜你喜欢
    • 2013-11-27
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多