【问题标题】:Strange error using strstr使用 strstr 的奇怪错误
【发布时间】:2018-01-15 00:52:22
【问题描述】:

我目前正在STM32F0 上为智能电表实施 SML 阅读器。 一切正常,但我在使用来自string.hstrstr 时遇到问题

现状:

我有一个 char 数组数据,其中包含通过 USART 传入的所有数据。它包含十六进制数和一个有效的文本字符串。

在这个字符串的某个地方有这个序列: {0x01,0x01,0x62,0x1b,0x52,0x00,0x55}.

我想使用strstr 查找此子字符串在数据字符串中的位置。

它适用于这个示例字符串,它始终位于数据字符串的开头:{0x1b,0x1b,0x1b,0x1b,0x01,0x01,0x01,0x01,0x76,0x05}

但如果我使用其他子字符串,它就不起作用了。

这是我的代码:

const char needle[] = {0x01,0x01,0x62,0x1b,0x52,0x00,0x55};
    if((needle_ptr = strstr(Data,needle)) == NULL){
        //No Active Power String detected
        flags &= ~NewPowervalue;    //Reset NewPowervalue flag
    }else{

        Powervalue = (needle_ptr[14]<<24) + (needle_ptr[15]<<16) + (needle_ptr[16]<<8) + (needle_ptr[17])/10000;
        //Extract and calculate Powervalue
        flags |= NewPowervalue;     //Set NewPowervalue flag
        Poweroutlets(&Powervalue);
        GPIOC->ODR ^= BLED;
    }

有人知道我做错了什么吗?

【问题讨论】:

  • 可能是 0x00 字符的出现是问题所在,strstr 将其解释为字符串终止符。
  • 一般来说,将这些来自 USART 的数据视为字符串数据对我来说似乎很愚蠢。一个字符串是“嘿,你好吗?”如果您不能用可打印的 ASCII 字符(或您使用的任何字符编码)表示所有数据,则不应使用字符串函数。如果您接收的数据中嵌入了字符串,如果您想在其上使用字符串函数,请先将其解析出来。处理二进制数据时使用memcpy和朋友,或者编写自己的解析函数。
  • 请注意,您很幸运 0x1b…0x05 'string' 有效,因为您没有用空字节 (0x00) 终止该字符串,并且 strstr() 读取超出了范围大批。如果您使用strstr() 或字符串处理函数,则必须确保处理的是以空值结尾的字符串。正如(至少)其中一个答案所指出的那样,memmem() 函数类似于strstr() 用于有限长度的内存工作。然而,它不是一个 POSIX 函数(更不用说标准 C),但它可能比所建议的更广泛可用(Linux、macOS、AIX ……拥有它)。
  • 有趣的是,memmem() 的 macOS 文档指出:_ 这个函数在 Linux libc 中被破坏,包括 5.0.9 版和 GNU libc 2.1 版之前。_ 用任何大小处理它一小撮你认为合适的盐。反正它可能不会影响你。
  • 只是一个琐碎的想法......这个来自 USART 的文本字符串 - 如果它可以包含任何 char 值,包括 NUL,你怎么知道开始/结束在哪里?跨度>

标签: c substring strstr


【解决方案1】:

当然不行,因为0x00是asciiz终止符,strstr()比较的是asciiz终止的字符串,所以在0x00就停止比较了。

您展示的另一个示例字符串有效,因为它不包含任何 0x00s。

因此,归结为您不想比较字符串(因为字符串是在 C 中定义的)而是内存区域。

因此,您要么必须使用memmem() 函数(如果您的运行时库有),要么自己编写,这应该不难。 (应该不难找到memmem()的一些实现的源代码。)

【讨论】:

  • 非常感谢。使用 memmem 可以正常工作!我没有在字符串的末尾添加 '\0',因为没有它也可以。所以我不再只是它了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
相关资源
最近更新 更多