字符串和内存操作函数

来源:互联网 发布:淘宝3d试衣技术 编辑:程序博客网 时间:2024/04/26 11:42
 

1.1 字符串操作函数说明

对一串字符的处理在应用编程中无处不在,其操作函数主要有两类:一类以str开头的函数,主要针对字符串进行处理;一类为mem开头的函数,针对一片内存进行处理,此类函数可以处理字符串和结构体。

1.1.1 字符串操作函数总结说明

1.   str与mem的含义

str开头的函数为字符串函数,字符串函数遇到'\0'结束符即终止操作,字符串最后一个字符即为'\0'字符。

mem开头的函数为一片内存操作函数,函数原型中包括处理长度,表示对一片内存空间的处理,这片内存中可以包含'\0'字符。

2.   会对目的串自动补’\0’字符的函数

常见有strcpy、sprintf、gets、strcat等不指定长度的字符串函数。

3.   strcpy与memcpy的比较

对strcpy、memcpy两函数差别说明如下:

①    strcpy用于字符串的复制,strcpy碰到源串'\0'字符即终止复制。

②    memcpy为一片内存空间的复制,复制时可以包括'\0'字符,一片内存空间或结构体变量之间的复制常用此函数。

③    strcpy(dest,src)表示把源字符串src复制到目的串dest中,当dest空间小于src长度时会造成内存溢出,从而让程序coredump。

④    memcpy (dest , src, n)表示复制src所指的内存内容前n个字节到dest所指的内存地址上。如果是字符串复制可以用strncpy代替,不过strncpy遇到'\0'字符会终止复制,可能复制不到n个字节。

⑤    两结构体变量之间的复制只能用memcpy函数。

4.   strcpy与strncpy的比较

对strcpy、strncpy两函数差别说明如下:

①    用strcpy函数复制时目的串后会自动补0,用strncpy函数复制时目的串后不会自动补0。

②    strncpy(dest, src, n)表示从src源串复制n个字节到dest目的串,但碰到'\0'字符时会提前终止复制。

③    用strncpy函数时,有时需要给目的串设置结束符('\0'),给一串字符设置'\0'的方式有两种,分别为string[n]=0或string[n]= '\0'。因为字符可以当做整型单独赋值,0表示ASCII编号的0;也可以当做字符赋值,字符赋值时特殊字符需用\来转义。字符'0'的ASCII编号为30,而字符'\0'的ASCII编号为0。

1.2 字符串函数操作

字符串函数是编程中常用到的函数,字符串按照使用用途可分为字符串初始化、取字符串长度、复制字符串、连接字符串、比较字符串、搜索字符串、分割字符串七大类。

1.   字符串初始化

(1)函数原型

                     memset(将一段内存空间填入某值)

 

 

所需头文件

#include <string.h>

函数说明

memset()会将参数s所指的内存区域前n个字节以参数c填入,然后返回指向s的指针。在编写程序时,若需要将某一数组作初始化,memset()会相当方便

函数原型

void * memset (void *s ,int c, size_t n)

函数传入值

s:字符串地址

c:初始化字符

n:初始化字符串长度

函数返回值

返回指向s的指针

附加说明

参数c虽声明为int,但必须是unsigned char,所以范围在0到255之间

使用场合

①   初始化字符串

②   初始化结构体

③   初始化malloc申请的内存空间

 

(2)memset函数说明

memset函数完成内存一片空间的初始化,对此函数使用方法说明如下:

①    字符串初始化:memset(string,0x00,sizeof(string)),string表示字符数组。

②    结构变量初始化:memset(&struct,0x00,sizeof(&struct)),struct表示结构变量。因为结构变量表示一片内存空间的抽象,需要用&得到结构变量地址。

③    字符串和结构变量使用前最好用memset函数进行初始化。

 

(3)memset应用代码范例

memset.c代码如下:

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int main()

{

    char s[30];

    char *p ;

    struct stu

    {

        int num;

        char name[20];

        char sex;

        float score;

    };

    struct stu boy1;

    p=(char *)malloc(1024);

    memset (s, 0x00, sizeof(s));

    memset(p, 0x00, 1024) ;

    memset(&boy1, 0x00, sizeof(struct stu)) ;

    return 0 ;

}

2.   取字符串长度

(1)函数原型

                      strlen(返回字符串长度)

 

 

所需头文件

#include <string.h>

函数说明

strlen()用来计算指定的字符串s的长度,不包括结束字符’\0’

函数原型

size_t strlen (const char *s)

函数传入值

s:字符串首地址

函数返回值

返回字符串s的字符数

(2)应用代码范例

strlen.c代码如下:

#include <stdio.h>

#include <string.h>

int main()

{

    char *str = "12345678";

    printf("str length = %d\n", strlen(str));

    return 0 ;

}

编译 gcc  strlen.c -o  strlen。

执行 ./strlen,执行结果如下:

str length = 8

3.   复制字符串

(1)函数原型

                       strcpy(复制字符串)

 

 

所需头文件

#include <string.h>

函数说明

strcpy()会将参数src字符串复制至参数dest所指的地址

函数原型

char *strcpy(char *dest,const char *src)

函数传入值

dest:目的串地址

src:源串地址

函数返回值

返回参数dest的字符串起始地址

附加说明

如果参数dest所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况,在编写程序时请特别留意,或者用strncpy()来取代

 

                        strncpy(根据长度复制字符串)

 

 

所需头文件

#include <string.h>

函数说明

strncpy()会将参数src字符串复制前n个字符至参数dest所指的地址

函数原型

char * strncpy(char *dest,const char *src,size_t n)

函数传入值

dest:目的串地址

src:源串地址

n:复制的字符数

函数返回值

返回参数dest的字符串起始地址

 

                       memcpy(复制内存内容)

 

 

所需头文件

#include <string.h>

函数说明

memcpy()用来复制src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'\0'而结束

函数原型

void * memcpy (void * dest ,const void *src, size_t n)

函数传入值

dest:目的串地址

src:源串地址

n:复制字节数

函数返回值

返回指向dest的指针

附加说明

①    指针src和dest所指的内存区域不可重叠

②    结构体之间的复制需要用memcpy,而不能用strcpy

 

                        memmove(复制内存内容)

 

 

所需头文件

#include <string.h>

函数说明

memmove()与memcpy()一样都是用来复制src所指的内存内容前n个字节到dest所指的地址上。不同的是,当src和dest所指的内存区域重叠时,memmove()仍然可以正确的处理,不过执行效率上会比使用memcpy()略慢些

函数原型

void * memmove(void *dest,const void *src,size_t n)

函数传入值

dest:目的串地址

src:源串地址

n:复制字节数

函数返回值

返回指向dest的指针

 

(2)应用代码

strcpy.c源代码如下:

#include <stdio.h>

#include <string.h>

int main()

{

    char a[30]="string(1)";

    char b[]="string(2)";

    printf("before strcpy() :%s\n",a);

    printf("after strcpy() :%s\n",strcpy(a,b));

 

    strncpy( &a[9], b, 9) ;

    a[18]='\0' ;

    printf("after strncpy():%s\n", a) ;

    return 0 ;

}

编译 gcc  strcpy.c -o  strcpy。

执行 ./strcpy,执行结果如下:

before strcpy() :string(1)

after strcpy() :string(2)

after strncpy():string(2)string(2)

 

memcpy.c源代码如下:

#include <stdio.h>

#include <string.h>

int main()

{

    char a[30];

    char b[30]="string\0string";

    int i;

 

    memset( a, 0x00, sizeof(a) ) ;

    strcpy(a,b);

    printf("strcpy():", a);

    for(i=0;i<30;i++)

        printf("%c",a[i]);

    printf("\n") ;

    memcpy(a,b,30);

    printf("memcpy():");

    for(i=0;i<30;i++)

        printf("%c",a[i]);

    printf("\n") ;

    return 0 ;

}

编译 gcc  memcpy.c -o  memcpy。

执行 ./memcpy,执行结果如下:

strcpy():string

memcpy():stringstring

4.   连接字符串

(1)函数原型

                        strcat(连接两字符串)

 

 

所需头文件

#include <string.h>

函数说明

strcat()会将参数src字符串复制到参数dest所指的字符串尾。第一个参数dest要有足够的空间来容纳要复制的字符串

函数原型

char *strcat (char *dest,const char *src)

函数传入值

dest:目的串地址

src:源串地址

函数返回值

返回参数dest的字符串起始地址

附加说明

如果参数dest所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况,在编写程序时请特别留意。

 

                         strncat(根据长度连接两字符串)

 

 

所需头文件

#include <string.h>

函数说明

strncat()会将参数src字符串复制n个字符到参数dest所指的字符串尾。第一个参数dest要有足够的空间来容纳要复制的字符串

函数原型

char * strncat(char *dest,const char *src,size_t n)

函数传入值

dest:目的串地址

src:源串地址

n:复制的字符数

函数返回值

返回参数dest的字符串起始地址

附加说明

strncat与strncpy不同,系统会对目的串结尾处自动补0

 

(2)应用代码范例

strcat.c源代码如下:

#include <stdio.h>

#include <string.h>

int main()

{

    char a[30]="string(1)";

    char b[]="string(2)";

    printf("before strcat(): %s\n",a);

    printf("after strcat(): %s\n",strcat(a,b));

    printf("after strncat(): %s\n",strncat(a,b,6));

    return 0 ;

}

编译 gcc  strcat.c -o  strcat。

执行 ./strcat,执行结果如下:

before strcat(): string(1)

after strcat(): string(1)string(2)

after strncat(): string(1)string(2)string

5.   比较字符串

(1)函数原型

                         strcmp(比较字符串)

 

 

所需头文件

#include <string.h>

函数说明

strcmp()用来比较参数s1和s2字符串。字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。strcmp()首先将s1第一个字符值减去s2第一个字符值,若差值为0则再继续比较下个字符,若差值不为0则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符'A'(65)和'b'(98)的差值(-33)

函数原型

int strcmp(const char *s1,const char *s2)

函数传入值

s1:串1

s2:串2

函数返回值

若参数s1和s2字符串相同则返回0。s1若大于s2则返回大于0的值。s1若小于s2则返回小于0 的值

 

                         strncmp(比较规定长度的字符串)

 

 

所需头文件

#include <string.h>

函数说明

用来将参数s1中前n个字符和参数s2字符串作比较

函数原型

int strcmp(const char *s1,const char *s2, size_t n)

函数传入值

s1:串1

s2:串2

n:比较字符串的长度

函数返回值

若参数s1和s2字符串相同则返回0。s1若大于s2则返回大于0的值。s1若小于s2则返回小于0 的值

 

                         memcmp(比较内存内容)

 

 

所需头文件

#include <string.h>

函数说明

memcmp()用来比较s1和s2所指的内存区间前n个字符。字符串大小的比较是以ASCII码表上的顺序来决定,次顺序亦为字符的值。memcmp()首先将s1第一个字符值减去s2第一个字符的值,若差为0则再继续比较下个字符,若差值不为0则将差值返回。例如,字符串"Ac"和"ba"比较则会返回字符'A'(65)和'b'(98)的差值(-33)

函数原型

int memcmp (const void *s1,const void *s2,size_t n)

函数传入值

s1:串1

s2:串2

n:比较字符串的长度

函数返回值

若参数s1和s2字符串相同则返回0。s1若大于s2则返回大于0的值。s1若小于s2则返回小于0 的值

附加说明

strcmp、strncmp碰到0字符即终止,而memcmp比较内容中可以包含0字符

 

                       忽略大小写比较字符串

 

 

所需头文件

#include <string.h>

函数说明

用来将参数s1中前n个字符和参数s2字符串作比较

函数原型

int strcasecmp(const char *s1, const char *s2)

int strncasecmp(const char *s1, const char *s2, size_t n)

函数传入值

s1:串1

s2:串2

n:比较字符串的长度

函数返回值

若参数s1和s2字符串相同则返回0。s1若大于s2则返回大于0的值。s1若小于s2则返回小于0 的值

 

(2)应用代码范例

strcmp.c源代码如下:

#include <stdio.h>

#include <string.h>

int main()

{

    char *a="aBcDeF";

    char *b="AbCdEf";

    char *c="aacdef";

    char *d="aBcDeF";

 

    printf("strcmp(a,b) : %d\n",strcmp(a,b));

    printf("strcmp(a,c) : %d\n",strcmp(a,c));

    printf("strcmp(a,d) : %d\n",strcmp(a,d));

    printf("strncmp(a,d,5 ) : %d\n",strncmp(a,d, 5));

    printf("memcmp(a,d,3) : %d\n",memcmp(a,d,3));

    printf("memcmp(a,b) : %d\n",strcasecmp(a,b));

    printf("memcmp(a,b,4) : %d\n",strncasecmp(a,b,4));

 

    return 0 ;

}

编译 gcc  strcmp.c -o  strcmp。

执行 ./strcmp,执行结果如下:

strcmp(a,b) : 1

strcmp(a,c) : -1

strcmp(a,d) : 0

strncmp(a,d,5 ) : 0

memcmp(a,d,3) : 0

memcmp(a,b) : 0

memcmp(a,b,4) : 0

6.   搜索字符串

(1)函数原型

                       strstr(在一字符串中查找指定的字符串)

 

 

所需头文件

#include <string.h>

函数说明

strstr()会从字符串haystack 中搜寻字符串needle,并将第一次出现的地址返回。

函数原型

char *strstr(const char *haystack, const char *needle)

函数传入值

haystack:源串

needle:搜索串

函数返回值

返回指定字符串第一次出现的地址,否则返回0

 

                      strchr(查找字符串中第一个出现的指定字符)

 

 

所需头文件

#include <string.h>

函数说明

strchr()用来找出参数s字符串中第一个出现的参数c字符的地址,然后将该字符出现的地址返回

函数原型

char * strchr (const char *s,int c)

函数传入值

s:源串

c:匹配字符

函数返回值

如果找到指定的字符则返回该字符所在地址,否则返回0

 

                       strrchr(查找字符串中最后出现的指定字符)

 

 

所需头文件

#include <string.h>

函数说明

strrchr()用来找出参数s字符串中最后一个出现的参数c字符的地址,然后将该字符出现的地址返回

函数原型

char * strrchr(const char *s, int c)

函数传入值

s:源串

c:匹配字符

函数返回值

如果找到指定的字符则返回该字符所在地址,否则返回0

 

(2)应用代码范例

strstr.c源代码如下:

#include <stdio.h>

#include <string.h>

int main()

{

    char * s="0123456789012345678901234567890";

    char *p;

 

    p= strstr(s,"901");

    printf("%s\n",p);

    p=strchr(s,'5');

    printf("%s\n",p);

    p=strrchr(s, '8');

    printf("%s\n",p);

 

    return 0 ;

}

编译 gcc  strstr.c -o  strstr。

执行 ./strstr,执行结果如下:

9012345678901234567890

56789012345678901234567890

890

7.   分割字符串

(1)函数原型

                       strtok(分割字符串)

 

 

所需头文件

#include <string.h>

函数说明

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

 

函数原型

char * strtok(char *s,const char *delim)

函数传入值

s:源串

delim:分割符

函数返回值

返回下一个分割后的字符串指针,如果已无从分割则返回NULL

 

(2)应用代码范例

strtok.c源代码如下:

#include <stdio.h>

#include <string.h>

int main(void)

{

    char str[] = "root:x::0:root:/root:/bin/bash:";

    char *token;

    token = strtok(str, ":");

    printf("%s\n", token);

    while ( (token = strtok(NULL, ":")) != NULL)

        printf("%s\n", token);

    return 0;

}

编译 gcc  strtok.c -o  strtok。

执行 ./strtok,执行结果如下:

root

x

0

root

/root

/bin/bash

1.3 字符类型测试函数

字符类型测试用来测试单个字符的类型。

(1)字符类型测试函数原型

头文件

#include <ctype.h>

函数原型

函数说明

int isalnum(int c)

测试字符是否为英文或数字

int isalpha(int c)

测试字符是否为英文字母

int isascii(int c)

测试字符是否为ASCII 码字符

int iscntrl(int c)

测试字符是否为ASCII 码的控制字符

int isdigit(int c)

测试字符是否为阿拉伯数字

int isgraph(int c)

测试字符是否为可打印字符(ASCII码33-126之间的字符)

int islower(int c)

测试字符是否为小写字母

int isprint(int c)

测试字符是否为包含空格在内可打印字符(ASCII码32-126之间的字符)

int isspace(int c)

测试字符是否为空格字符

int ispunct(int c)

测试字符是否为标点符号或特殊符号

int isupper(int c)

测试字符是否为大写英文字母

int isxdigit(int c)

测试字符是否为16进制数字

返回值

测试正确:返回TRUE或大于零的值

测试错误:NULL(0)

 

(2)应用代码范例

ischar.c源代码如下:

#include <stdio.h>

#include <ctype.h>

int main()

{

    char str[]="123@#FDsP[e?";

    int i;

    for(i=0;str[i]!=0;i++)

        if(islower(str[i])) printf("%c is a lower-case character\n",str[i]);

    printf("1=%d\n", isxdigit('1')) ;

    printf("2=%d\n", isxdigit('2')) ;

    printf("v=%d\n", isxdigit('v')) ;

    printf("U=%d\n", isupper('U')) ;

    printf("u=%d\n", isupper('u')) ;

 

    return 0 ;

}

编译 gcc ischar.c -o  ischar。

执行 ./ischar,执行结果如下:

s is a lower-case character

e is a lower-case character

1=4096

2=4096

v=0

U=256

u=0

1.4 字符串转换函数

字符串转换函数完成数字到字符串、字符串到数字的转换功能,字符串转换函数是在应用编程中经常使用到的函数。

(1)字符串转换函数原型

                        atof(将字符串转换成浮点型数)

 

 

所需头文件

#include <stdlib.h>

函数说明

atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2

函数原型

double atof(const char *nptr)

函数传入值

nptr:浮点型指针

函数返回值

返回转换后的浮点型数

 

                        atoi(将字符串转换成整型数)

 

 

所需头文件

#include <stdlib.h>

函数说明

atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回

函数原型

int atoi(const char *nptr)

函数传入值

nptr:短整型指针

函数返回值

返回转换后的整型数

 

                         atol(将字符串转换成长整型数)

 

 

所需头文件

#include <stdlib.h>

函数说明

atol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回

函数原型

long atol(const char *nptr)

函数传入值

nptr:长整型指针

函数返回值

返回转换后的长整型数

 

                        整型、长整型、浮点型转换为字符串

 

 

所需头文件

#include <stdio.h>

函数说明

通常可以用sprintf作变量类型转换

函数原型

int sprintf( char *str,const char * format, …)

转换例子

整型转换为字符串:sprintf(str,  "%d", 30)

长整型转换为字符串:sprintf(str, "%ld", 300000)

浮点型转换为字符串:sprintf(str, "%.2f", 90.90)

 

(2)应用代码范例

ato.c源代码如下:

#include <stdio.h>

#include <stdlib.h>

int main()

{

    char a[]="-100";

    char aa[]="1000000000";

    char *aaa="-100.23";

    int c;

    long cc ;

    float ccc ;

    char str[30];

 

    c=atoi(a);

    cc = atol(aa) ;

    ccc = atof(aaa) ;

    printf("c=%d\n",c);

    printf("cc=%ld\n",cc);

    printf("ccc=%.2f\n",ccc);

    sprintf(str,"%d%ld%.2f",c, cc,ccc) ;

    printf("str=%s\n", str) ;

 

    return 0 ;

}

编译 gcc ato.c -o  ato。

执行 ./ato,执行结果如下:

c=-100

cc=1000000000

ccc=-100.23

str=-1001000000000-100.23

 

摘录自《深入浅出Linux工具与编程》

原创粉丝点击