比较strcmp, strncmp和memcmp
本文最后更新于1529天前,其中的信息可能已经有所发展或是发生改变。

做到一道挺简单逆向题

这是伪代码:

看到strncmp这个函数顺便说一下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),这样一来就达到了目的

附:strcmp,strncmp,memcmp的Linux的源代码

/** 
* strcmp - Compare two strings 
* @cs: One string 
* @ct: Another string 
*/ 
int strcmp(const char *cs, const char *ct) 

        signed char __res;

        while (1) { 
                if ((__res = *cs - *ct++) != 0 || !*cs++)

//比较到结束符/0,时,已经做了__res = *cs - *ct了,但是此时*cs和*ct的值都为/0,所以返回肯定为0 
                        break; 
        } 
        return __res; 

/** 
* strncmp - Compare two length-limited strings 
* @cs: One string 
* @ct: Another string 
* @count: The maximum number of bytes to compare 
*/ 
int strncmp(const char *cs, const char *ct, size_t count) 

        signed char __res = 0;

        while (count) { 
                if ((__res = *cs - *ct++) != 0 || !*cs++)                  //比较到结束符/0,时,已经做了__res = *cs - *ct了,所以不等长度时,肯定返回不为0 
                        break; 
                count--; 
        } 
        return __res; 

/** 
* memcmp - Compare two areas of memory 
* @cs: One area of memory 
* @ct: Another area of memory 
* @count: The size of the area. 
*/ 
int memcmp(const void *cs, const void *ct, size_t count) 

        const unsigned char *su1, *su2; 
        int res = 0; 
        for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) 
                if ((res = *su1 - *su2) != 0) 
                        break; 
        return res; 
}

测试程序:

#include 
#include 
#include

using namespace std;

int main() 

string str1 = "abcd"; 
string str2 = "abcdef";

int result1 = 0; 
int result2 = 0; 
int result3 = 0;

result1 = strcmp(str1.c_str(),str2.c_str()); 
result2 = strncmp(str1.c_str(),str2.c_str(),7); 
result3 = memcmp(str1.c_str(),str2.c_str(),7);

cout<<"strcmp: "<<result1<<endl;
cout<<"strncmp: "<<result2<<endl;
cout<<"memcmp: "<<result3<<endl;< p="">

getchar(); 
return 0; 
}

得出结论:

示例字符串 str1 = "abcd";

           srr2 = "abcdef";

(1)strmcp比较结果为非0(不等)。

(2)strncmp,若count <= 4,结果为0(相等);若count > 4,则结果-101(因为最短的字符串长度为4,所以比较到第5个字符即结束,值为'/0'的ascii码减去‘e’的ascii值)。

(3)memcpy,若count <= 4,则结果为0(相等);若count > 4,则结果为-1(比较到第count个字节即结束)

点击数:279

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇