【C语言总结】C语言字符串、字符和字节

1.字符串基础

字符串是一串零个或多个字符,并且以一个位模式的0的NUL字节结尾。NUL字节是字符串的终止符,但是本身并不是字符串的一部分,所以字符串的长度并不包括NUL字节。

2.字符串长度

字符串的长度就是它所包含的字符个数,可以通过对字符进行计数来计算字符串的长度。

但是我们不需要这样做,C的标准库中有这样的函数。

库函数strlen的原型如下:

size_t strlen(const char* string);

注:size_t这个类型是一个无符号整数类型,在头文件stddef.h中定义。

3.不受限制的字符串函数

3.1复制字符串

用于复制字符串的函数是strcpy,原型如下:

char* strcpy(char* dst, const char* src);

这个函数把参数src字符串复制到dst函数,如果参数src和dst在内存中出现重叠,其结果是未定义的,由于dst参数将进行修改,所以它必须是个字符数组或者是一个指向动态内存分配内存的数组的指针,不能使用字符串常量。

strcpy无法判断目标字符数组的长度,所以使用strcpy时,必须保持目标参数具有的空间的大小足够,不然src里面多余的字符将覆盖原先存储与数组后面的内存空间的值。

3.2连接字符串

想要把一个字符串添加到另一个字符串后面,可以使用strcat函数,是字符串拼接函数,原型如下:

char* strcat(char* dst, const char* src);

strcat函数要求dst参数原先已经包含了一个字符串(可以是空字符串),它找到这个字符串的末尾并且把src字符串的一份拷贝添加到这个位置,如果src和dst的位置发生重叠,结果是未定义的。

3.3函数的返回值

strcpy和strcat都返回它们的第一个参数的一份拷贝,就是一个指向目标字符数组的指针,由于它们返回这种类型的值,所以可以嵌套的调用这些函数,例:

strcat(strcpy(dst, a), b);

3.4字符串比较

库函数strcmp用于比较两个字符串串,原型如下:

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

srtcmp函数是从两个字符串的首字符开始一个一个比较两个字符串的字符,如果碰见两个字符不匹配,不匹配中的字符中 比较“小”的那个字符所在的字符串小于另一个字符串,如果s1小于s2,strcmp函数就返回一个小于0的值,如果s1大于s2就防护一个大于0的值如果两个字符串相等函数就返回0。

4.长度受限的字符串函数

标准库还定义了一些函数以不同的方式处理字符串,这些函数接受一个显示的长度参数,用于限定的复制或比较的字符数,这些函数提供了一种方便的机制以反之长字符串溢出。

原型如下所示:

char* strncpy(char* dst, const char* src, size_t len);

char* strncat(char* dst, const char* src, size_t len);

char* strncmp(const char* s1, const char* s2, size_t len);

和strcpy一样,strncpy把源字符串的字符复制到目标数组,然而它正好向dst写入len个字符,如果src字符串的字符数量小于len个,那么dst数组就用额外的NUL字节填充到len长度,如果大于或者等于len,那么就只有len个字符被复制到dst中,注意,它的结果将不会以NUL字节结尾。

strncat也是一个长度受限的函数,它是从src中复制最多len个字符到目标数组后面,但是strncat会在字符串后面添加一个NUL字节,而且它不会对目标数组用NUL进行填充。

strncmp最多比较len个字节,如果两个字符串的前len个字符串相等,就返回0,如果在len个字节之前有不相等的,函数就像strcmp一样停止比较并返回结果。

5.字符串查找基础

5.1查找一个字符

在一个字符串中查找一个字符最容易的方法就是strchr和strrchr函数,函数原型如下:

char* strchr(const char* str, int ch);
char* strrchr(const char* str, int ch);

strchr函数在字符串str中查找到字符ch第一次出现的位置,找到后函数返回一个指向该指针位置的指针,如故宫该字符并不存在于字符串中,则返回一个NULL指针。

strrchr的功能和strchr基本一致,只是它返回的是字符ch最后一次在该字符串中出现的位置。

5.2查找任何几个字符

strpbrk是个长江的函数,它是查找任何一组字符第一次在字符串中出现的位置,函数原型如下:

char* strpbrk(const char* str, const char* group);

这个函数返回一个指向str中第一个匹配group中任何一个字符的字符位置,如果未找到匹配即返回NULL。

5.3查找一个子串

为了在字符串中查找一个字串,我们可以使用strstr函数,函数原型如下:

char* strstr(const char* s1, const char* s2);

这个函数在s1中查找整个s2第一次出现的起始位置并返回一个指向该位置的指针,如果s2并没有完整的出现在s1的任何地方,函数将返回一个NULL指针,如果s2是一个空字符串函数就返回s1。

6.高级字符串查找

6.1查找一个字符串前缀

strspn和strcspn函数用于在函数的起始位置对字符计数,函数原型如下:

size_t strspn(const char* str, const chat* group);
size_t strcspn(const char* str, const char* group);

group字符串指定一个或多个字符,strspn返回str起始部分匹配group中任意字符的字符数,例如,如果group包含了空格、制表符灯空白字符,那么这个函数将返回str起始部分空白字符的数目。

strcspn函数和strspn正好相反,它对str字符串起始部分中不与group中任何字符匹配的字符进行计数。

6.2查找标记

strtok函数从字符串中隔离哥哥贩毒的称为标记的部分并丢弃分隔符,函数原型如下:

char* strtok(char* str, const char* sep);

sep参数是个字符串,定义了用作分隔符的字符集合。第一个参数指定一个字符串,它包含0个或多个由sep字符串中一个或者多个分隔符分隔的标记,strtok找到str的下一个标记并将其用NUL结尾然后返回一个指向这个标记的指针。

7.错误信息

如果调用一些函数请求操作系统执行一些功能时如果出现错误,操作系统通过设置一外部的整形变量errno进行错误代码报告,strerror函数把其中一个错误代码作为参数并返回一个指向用于描述错误的字符串的指针,函数原型如下:

char* strerror( int error_number );

8.字符操作

标准库包含了两组函数用于操作单独的字符,它们的原型位于头文件ctype.h,第一组函数用于对字符进行分类,第二组函数用于转换字符。

8.1字符分类

如下图:
【C语言总结】C语言字符串、字符和字节_第1张图片

8.2字符转换

转换函数把大写字母转化为小写字母或者把小写字母转换为大写字母,函数原型如下:

int tolower(int ch);
int toupper(int ch);

toupper函数返回其参数对应的大写方式,toulower函数返回其参数的对应小写形式。

9.内存操作

字符串由一个NUL字节结尾,所以字符串内部不能包含任何NUL字符。但是非字符串数据内部如果包含零值的话,字符串函数就无法处理这种类型的数据,所以我们有另一组相关的函数。函数原型如下:

void* memcpy(void* dst, const void* src, size_t length);
void* memmove(void* dst, const void* src, size_t length);
void* memcmp(const void* a, const void* b, size_t length);
void* memchr(const void* a, int ch, size_t length);
void memset(void* a, int ch, size_t length);

每个原型都包括了一个显示的参数说明需要处理的字节数,但是和strn开头的函数不同,它们在遇到NUL字节时并不会停止操作。

一些警告

1.应该使用有符号数的表达式中使用strlen(因为它的返回值时size_t)

2.在表达式中混用有符号数和无符号数

3.使用strcpy函数把一个长字符串复制到一个较短的数组中导致溢出

4.使用strcat函数把一个字符串添加到一个数组中导致数组溢出

5.把strcmp函数的返回值当作布尔值进行测试

6.把strcmp函数的返回值与1和-1进行比较

7.使用strncpy函数产生不以NUL字节结尾的字符串

8.使用strncpy函数产生不以NUL字节结尾的字符串

9.把strncpy函数和strxxx族函数混用

10.忘了strtok函数将会修改它所处理的字符串

11.strtok函数是不可再入的

你可能感兴趣的:(C语言总结)