待到秋来九月八,我花开后百花杀
求字符串长度
strlen
- 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
- 参数指向的字符串必须要以 ‘\0’ 结束。
- 注意函数的返回值为size_t,是无符号的( 易错 )
- 学会strlen函数的模拟实现
- 循环字符串,sum计算总数。
- 设置头指针和尾指针,返回头指针和尾指针的差值。
- 递归完成,“\0”作为递归结束条件。
代码模拟实现(递归和迭代方法模拟实现):https://github.com/GagaAutom/C-programming-language/blob/master/strlen/strlen/strlen.c
长度不受限制的字符串函数
strcpy
字符串复制函数
- Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point). 将source指向的C字符串复制到destination指向的数组中,包括终止的空字符(并在该点停止)。
- 源字符串必须以 ‘\0’ 结束。 会将源字符串中的 ‘\0’ 拷贝到目标空间。
- 该函数是有返回值的,不仅仅局限于用destination输出
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
- 学会模拟实现。
双指针,一个指向destination,另一个指向source,把source复制到destination,记得复制”\0“.
代码模拟实现:https://github.com/GagaAutom/C-programming-language/blob/master/strcpy.c
真实内部程序:https://github.com/GagaAutom/C-programming-language/blob/master/ture_strcpy.c
strcat
字符串拼接函数
- Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.将source字符串的副本附加到destination字符串。目标中的终止空字符将被source的第一个字符覆盖,并且在由destination中的两个字符串联而成的新字符串的末尾包含一个空字符。
- 源字符串必须以 ‘\0’ 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
- 字符串自己给自己追加,如何?
会出现死循环
原因是:会在destination数组中无限添加内容,无法遇到“\0”停止。
模拟实现:
char * _strcat(char * destination, const char * source)
{
int i = 0;
int count = 0;
while (source[count] != '\0') {
if (destination[i] == '\0') {
destination[i] = source[count];
destination[i + 1] = '\0';
count++;
}
i++;
}
destination[i + count] = '\0';
return destination;
}
代码模拟实现:https://github.com/GagaAutom/C-programming-language/blob/master/strcat.c
真实内部程序:https://github.com/GagaAutom/C-programming-language/blob/master/ture_strcat.c
strcmp
字符串比较
- This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.
- 标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字 - 由ASCII码值决定字符串大小
真实内部程序:https://github.com/GagaAutom/C-programming-language/blob/master/ture_strcmp.c
长度受限制的字符串函数介绍
strncpy
- Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.将source的前几个字符复制到destination。如果在复制num个字符之前找到source字符串的结尾(由空字符发出信号),则用0填充destination,直到总共写入num个字符为止。
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
代码模拟实现:https://github.com/GagaAutom/C-programming-language/blob/master/imitate_strncpy.c
strncat
- Appends the first num characters of source to destination, plus a terminating null-character.将source的前几个字符附加到destination,再加上一个终止的空字符。
- If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.如果source中C字符串的长度小于num,则只复制不超过终止空字符的内容。
代码模拟实现:https://github.com/GagaAutom/C-programming-language/blob/master/imitate_strncat.c
strncmp
- 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
代码模拟实现:https://github.com/GagaAutom/C-programming-language/blob/master/imitate_strncmp.c
字符串查找
strstr
- Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.返回指向str1中第一个str2的指针,如果str2不是str1的一部分,则返回空指针。
举例:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="This is a simple string";
char * pch;
pch = strstr (str,"simple");
strncpy (pch,"sample",6);
puts (str);
return 0;
}
真实内部程序:https://github.com/GagaAutom/C-programming-language/blob/master/ture_strstr.c
strtok
分割字符串
- delimiters参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由delimiters字符串中一个或者多个分隔符分割的标记。
- strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。(也就是说在strtok内把str设置为了static,当函数调用完成一次时不释放。)
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
举例:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
strtok特点就是可以输入多个符号对字符串分割。
错误信息报告
strerror
- 返回错误码,所对应的错误信息。
举例说明:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
FILE * pFile;
pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("Error opening file unexist.ent: %s\n",strerror(errno));
return 0;
}
42种错误告警:
0: No error
1: Operation not permitted
2: No such file or directory
3: No such process
4: Interrupted function call
5: Input/output error
6: No such device or address
7: Arg list too long
8: Exec format error
9: Bad file descriptor
10: No child processes
11: Resource temporarily unavailable
12: Not enough space
13: Permission denied
14: Bad address
15: Unknown error
16: Resource device
17: File exists
18: Improper link
19: No such device
20: Not a directory
21: Is a directory
22: Invalid argument
23: Too many open files in system
24: Too many open files
25: Inappropriate I/O control operation
26: Unknown error
27: File too large
28: No space left on device
29: Invalid seek
30: Read-only file system
31: Too many links
32: Broken pipe
33: Domain error
34: Result too large
35: Unknown error
36: Resource deadlock avoided
37: Unknown error
38: Filename too long
39: No locks available
40: Function not implemented
41: Directory not empty
42: Illegal byte sequence
字符操作
字符分类函数
以下都是对单个字符的操作
函数 | 如果函数的参数符合下列条件就返回真 |
---|---|
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母a ~ f,大写字母A ~ F |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母a ~ z或A ~ Z |
isalnum | 字母或者数字,a ~ z,A ~ Z,0 ~ 9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
字符转换
int tolower ( int c );
//将一个字符转成小写
int toupper ( int c );
//将一个字符转成大写
内存操作函数
注意!所有内存操作的操作基本单位都是字节。
memcpy
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到 ‘\0’ 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的。
- 可以拷贝任意类型,并不在意拷贝的内容,是对内存上的值进行的复制。
memmove
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
真实内部程序:https://github.com/GagaAutom/C-programming-language/blob/master/ture_memmove.c
memset
- 将ptr指向的内存块的前num个字节设置为指定值(解释为unsigned char)
- 内存操作为字节,也就是改为特定值时,都是把一个字节内的内存改为了指定数。
memcmp
- 比较从ptr1和ptr2指针开始的num个字节