当前位置: 首页 > news >正文

【strstr()函数的局限】strstr()检测不到存在的字符/数据/strcmp, strncmp和memcmp

   在单片机调试的的时候,发现目标‘字符串’中的 目标字符,strstr()函数竟然检测不到(比较不出来)返回的时候0x00地址(NULL),很是奇怪,最后分析发现,原来是目标‘字符串’中含有0x00数据,strstr()函数碰到0x00就终止了查找,所以0x00后面的目标字符无法查到,strstr()返回的是0x0地址,指向的字符是0x00上的字符。

  在用strstr查找之前加了一个剔除0x00数据才小程序,去掉待检数组中的0x00数据,问题就解决了。

void  remove_out_0x00_dat(char *in_buff, int data_len)
{
    int str_len = 0;
    for(int i = 0; i < data_len; i++)
    {
        if(in_buff[i] != 0x00)
        {
            in_buff[str_len] = in_buff[i];
            str_len++;
        }
    }
}

【strstr()函数的局限】strstr()检测不到存在的字符/数据/strcmp, <wbr>strncmp和memcmp

 strcmp, strncmp和memcmp的区别

函数:int memcmp (const void *a1, const void *a2, size_t size) 

       函数memcmp用于比较字符串s1与s2的前size个字符。

      如果两上字符块相同,memcmp将返回0。

函数:int strcmp (const char *s1, const char *s2) 

       这个函数用来比较s1和s2字符串,这个函数将返回一个值,它的符号与第一对不同的字符的比较结果相关。

      如果两个字符串相等的话,strcmp将返回0。

       如果s1是s2的一个子串的话,s1小于s2

此外还有函数 

    int strncmp (const char *s1, const char *s2, size_t size) 

    此函数与strcmp极为类似。不同之处是,strncmp函数是指定比较size个字符。也就是说,如果字符串s1与s2的前size个字符相同,函数返回值为0。

功能比较:

     二者都可以用于字符串的比较,但是二者是有比较大的差异的,因为strcmp是按照字节(byte-wise)比较的,并且比较的过程中会检查是否出现了"/0"结束符,一旦任意一个字符串指针前进过程中遇到结束符,将终止比较。而memcmp函数是用于比较两个内存块的内容是否相等,在用于字符串比较时通常用于测试字符串是否相等,不常进行byte-wise的字符串比较。如果要比较的对象中包含一些由于边界对齐需求而填入结构对象中的空格、联合 (union)结束的额外空格、字符串所分配的空间未使用完的部分引起的“holes”的话,最好使用memcmp来完成。这些“holes”的内容是不确定的,在执行byte-wise比较时结果也是不明确的。

效率差异:

     strcmp比较的字符串,而memcmp比较的是内存块,strcmp需要时刻检查是否遇到了字符串结束的 /0 字符,而memcmp则完全不用担心这个问题,所以memcmp的效率要高于strcmp

使用示例:

给出一个如下的结构定义:

struct foo
{
    unsigned char tag;
    union
    {
        double f;
        long i;
        char *p;
    } value;
};

      如果要比较两个struct foo对象的话,建议最好使用memcmp。

     在给出一个字符串比较的例子,判断字符串str中前四个中字符是否为 0x80100001,因为0x00对于字符串而言,这是个结束符,如果使用strncmp的话strncmp(str,"/x80/x10/x00 /x01",4)的话,实际效果是只判断了是否含有0x8010,也就是说一旦str中前两个字符为0x8010就返回0,表示相同了,显然这是不正确的!此时应该使用memcmp(str,"/x80/x10/x00/x01",4),这样一来就达到了目的

相关文章:

  • 【ZIGBEE资料】zigbee资料下载
  • 【指针有效性】指针有效性的有效性检测的必要性!!
  • 【GPRS透明传输】GPRS透明传输
  • 【GPRS拨号错误】GPRS 某条指令一直ERRO
  • 【IAR编译和单片机】IAR编译和单片机的一些积累
  • 【C++】C++获取系统日期时间
  • 【单片机重启】MSP430重启/频繁重启/跑飞 原因分析
  • 【堆和栈的区别】堆heap 和栈stack有什么区别(代码区、常量区、静态区(全局区)、堆区、栈区)...
  • 【MODBUS】 协议
  • 【单机片调试】开发调试MSP430 遇到的问题总结
  • 【单片机程序和RAM】程序在RAM中调试的运行方式程序固化后运行方式
  • 【关于单片机的N多问题】关于单片机的N多问题
  • 【volatile关键字】 详解C中volatile关键字(IAR 优化等级问题)
  • 【下载进去无法运行】MSP430 程序能下载进去却无法运行
  • 【文章收藏】文章收藏
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • Debian下无root权限使用Python访问Oracle
  • gitlab-ci配置详解(一)
  • HTML5新特性总结
  • Java比较器对数组,集合排序
  • SpingCloudBus整合RabbitMQ
  • vue中实现单选
  • WePY 在小程序性能调优上做出的探究
  • 回流、重绘及其优化
  • 简析gRPC client 连接管理
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 理清楚Vue的结构
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 由插件封装引出的一丢丢思考
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • Nginx实现动静分离
  • scrapy中间件源码分析及常用中间件大全
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • 整理一些计算机基础知识!
  • #162 (Div. 2)
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (一)WLAN定义和基本架构转
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET 材料检测系统崩溃分析
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .net程序集学习心得
  • .Net组件程序设计之线程、并发管理(一)
  • @AliasFor注解
  • @Autowired和@Resource的区别
  • @Bean注解详解
  • @ComponentScan比较
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [04]Web前端进阶—JS伪数组
  • [ACL2022] Text Smoothing: 一种在文本分类任务上的数据增强方法
  • [android]-如何在向服务器发送request时附加已保存的cookie数据