mem系列与str系列函数了解

系列函数通常处理内存内容,而Str通常处理字符串,这俩个家族系列函数经常会使用,在网上搜集了一些资料进行了整理,方便自己以后查阅,下面介绍了memcpy,strcpy,strncpy,memmove,memcmp,strcmp,strcat,strstr,strtok等函数:

一 拷贝函数

函数名称memset

函数原型:void *memset(void *s, int ch, size_t n);
函数解释:将s中前n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
最常见的错误:memset是按字节填充的,对其他多余一个字节的类型填充要注意

函数名称:memmove

函数原型:void memmove( void dest, const void* src, size_t count );

函数功能:由src所指内存区域复制count个字节到dest所指内存区域。
相关函数:memset、memcpy
memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前
将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。

函数名称strlen

函数原型:extern unsigned int strlen(char *s);
strlen(char*)函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个’\0’,如果你只定义没有给它赋初值,
这个结果是不定的,它会从aa首地址一直找下去,直到遇到’\0’停止。
而sizeof()返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个取字节运算符,strlen是函数。

函数名称:strcat

函数原型:extern char *strcat(char *dest,char *src);
重点内容:函数功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)并添加’\0’。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

函数名称:strstr

函数原型:extern char *strstr(char *str1, const char *str2);
语法
* strstr(str1,str2)
str1: 被查找目标 string expression to search.
str2: 要查找对象 The string expression to find.
返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
char *strtok(char s[], const char *delim);

函数名称:strtok

函数功能:解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
例如:strtok(“abc,def,ghi”,”,”),最后可以分割成为abc def ghi.尤其在点分十进制的IP中提取应用较多。

strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串,参数delim则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回指向被分割出片段的指针。

函数名称: memcpy

函数原型:void *memcpy(void *dest, const void *src,size_t n);

函数功能:内存拷贝;将src指向内存地址的连续N个指针位置的内容拷贝至dest指针指向的位置

函数返回:无

参数说明
dest — 目的内存空间指针
src — 源内存
n — 拷贝指针位置个数

# include <memory>
include <iostream>

include <string>

void main() 
{ 
char * src = “Hello Frankie World !”; 
char * dest = new char[50]; 
memset(dest,0,50); 
memcpy(dest,src,7); 
std::cout<<”dset值为:”<<std::endl; 
Out(dest);

}

函数名称:memccpy

函数原型:void * memccpy(void *dest, void *src, unsigned char c, unsigned int count);

函数功能:由src所指内存区域复制不多于count个字节到dest所指内存区域,如果第一次遇到字符c则停止复制

函数返回:如果c没有被复制,则返回NULL,否则,返回字符c 后面紧挨一个字符位置的指针

使用:

int  main() 

{ 

    char *src = "Welcome to Frankie world! sorry, I love you!"; 

    char dest[80]; 

    char *ptr; 

    ptr = (char *)memccpy(dest, src, '!', strlen(src)); 

    if (ptr) 

    { 

        *ptr = '\0'; 

        printf("The character was found: %s\n", dest); 

    } 

    else 

        printf("The character wasn't found\n"); 

    return 0;

}

说明:

memccpy只会碰到一个指定字符就停止复制

函数名称:memmove

函数原型:void memmove( void dest, const void* src, size_t count );

函数功能:由src所指内存区域复制count个字节到dest所指内存区域。

说明:

函数memcpy()从source指向的区域向dest指向的区域复制count个字符,如果两数组重叠,不定义该函数的行为。

而memmove(),如果两函数重叠,赋值仍正确进行。

memcpy函数假设要复制的内存区域不存在重叠,如果你能确保你进行复制操作的的内存区域没有任何重叠,可以直接用memcpy,且其效率会比memcpy高;

如果你不能保证是否有重叠,为了确保复制的正确性,你必须用memmove。

函数名称:strcpy

函数原型:char strcpy(char dest, const char *src);

函数功能:字符串拷贝;把从src地址开始且含有\0结束符的字符串复制到以dest开始的地址空间

函数返回:dest字符串指针

相关说明: src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

memcpy与strcpy区别:

1、

复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。

2、

复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符”\0”才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。

3、

用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

函数名称: strncpy

函数原型:char * strncpy( char *dest, char *src, size_t num );

函数功能:

复制src中的内容(字符,数字、汉字….)到dest,复制多少由num的值决定,返回指向dest的指针。如果遇到null字符(’\0’),且还没有到num个字符时,就用(num - n)(n是遇到null字符前已经有的非null字符个数)个null字符附加到destination。注意:并不是添加到destination的最后,而是紧跟着由source中复制而来的字符后面

函数返回: dest指针

使用方法

相关说明:

如果n > dest串长度,dest栈空间溢出产生崩溃异常。

一般情况下,使用strncpy时,建议将n置为dest串长度(除非你将多个src串都复制到dest数组,并且从dest尾部反向操作),复制完毕后,为保险起见,将dest串最后一字符置NULL,避免发生在第2)种情况下的输出乱码问题。当然喽,无论是strcpy还是strncpy,保证src串长度

2比较函数

函数名称:memcmp

函数原型:int memcmp (const void *S1, const void *S2, size_t size)
函数功能:用于比较内存数据S1与S2的前size个字符,如若相同,返回0
函数返回:如果S1,S2相同返回0,不相同返回-1
参数说明: S1—待比较内存数据1
S2—待比较内存数据2
size—比较内存数据个数

函数名称:memicmp

函数原型:int memicmp (const void *S1, const void *S2, size_t size)
函数功能:用于比较内存数据S1与S2的前size个字符,如若相同,返回0
特别注明:相对于memcmp而言,memicmp不区分字母大小写
函数返回:如果S1,S2相同返回0,不相同返回-1

用法:

void main()
{
   int nResult = -2;
   int nCount = 3;
   char * S1 = "ABC";
   char * S2 = "abc";
   nResult = memicmp(S1,S2,nCount);


  if(nResult == 0)
  {
    Out(S1);
    Out(S2);
    std::cout<<"S1 与 S2 相同 ,不区分大小写"<   }
}

结果:
wKioL1Mf1YeC8NQYAAAhcfnw1IQ669.jpg

函数名称:strcmp

函数原型:int strcmp(const char S1,const char S2);
函数功能:比较S1与S2字符串
函数返回
当s1
当s1==s2时,返回值= 0
当s1>s2时,返回正数 注意不是1
即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇’\0’为止。如:
“A”<”B” “a”>”A” “computer”>”compare”
特别注意:
strcmp(const char s1,const char s2)这里面只能比较字符串,不能比较数字等其他形式的参数。
参数说明:
S1:待比较字符串S1
S2:待比较字符串S2

函数名称:strncmp

函数原型:int strncmp (const char *s1, const char *s2, size_t size)
函数功能:比较S1与S2字符串前size个字符的不同
函数返回
此函数功能即比较字符串str1和str2的前maxlen个字符。如果前maxlen字节完全相等,返回值就=0;在前maxlen字节比较过程中,如果出现str1[n]与str2[n]不等,则返回(str1[n]-str2[n])。

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

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

实战: 编程输出网卡信息


#include <stdio.h>
#include <string.h>
#include <errno.h>
int main (int argc, char **argv)
{
    FILE       *fp;            //定义FILE *类型的句柄,以便从文件流中直接读取
    char       buf[512];
    char       *p1, *p2, *p3;
    char       ipaddr[16];
    char       netmask[16];

    fp = popen("ifconfig eth0", "r");    //执行popen函数
    if( fp == NULL)
    {
        printf("popen failure: %s\n", strerror(errno));
        return 0;
    }

    while( fgets(buf, sizeof(buf), fp)> 0)    //调用fgets()函数,有一系列获取ifconfig eth0执行结果
    {
        if( (p1=strstr(buf, "inet addr:")) != NULL ) //strstr()函数用于匹配有inet addr所在首地址
        {
            printf("%s", buf);

            p2=strchr(p1, ':');                     //找到‘:’字符首次出现的地址给p2
            p3=strchr(p2, ' ');                     //找到‘ ’字符首次出现的地址给p3
            memset(ipaddr, 0, sizeof(ipaddr));
            strncpy(ipaddr, p2+1, p3-p2);           //src为ipaddr,dst为p2+1,数据长度为p3-p2
            printf("IP address: %s\n", ipaddr);

            p2=strrchr(p1, ':');                    //找到最后一次出现‘:’的地址给p2
            p3=strrchr(p2, '\n');
            memset(netmask, 0, sizeof(netmask));
            strncpy(netmask, p2+1, p3-p2);     
            printf("Netmask address: %s\n", netmask);

        }
    }

    pclose(fp);


    return 0;
} /* ----- End of main() ----- */


程序执行结果如下
这里写图片描述

FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);

popen() 通过type是r还是w确定command的输入/输出方向,r和w是相对command的管道而言的。r表示command从管道中读入,w表示 command通过管道输出到它的stdout,popen返回FIFO管道的文件流指针。pclose则用于使用结束后关闭这个指针。
fread和 fgets的区别:
fread :以字节位计算长度,按照指定的长度和次数读取数据,遇到结尾或完成指定长度读取后停止.
fgets :整行读取,遇到回车换行或结尾停止.在文本方式时使用.
fwrite为fput的别名

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值