上章我们简单介绍了几个字符串函数,这里先补充几个。
嘿咻咻咻咻咻,鸡汤来咯。
目录
char * strtok ( char * str , const char * sep );
这个是cplusplus上的介绍,简单介绍:
sep 参数是个字符串,定义了用作分隔符的字符集合。第一个参数指定一个字符串,它包含了 0 个或者多个由 sep 字符串中一个或者多个分隔符分割的标 记。strtok 函数找到 str 中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容 并且可修改。)strtok 函数的第一个参数不为 NULL ,函数将找到 str 中第一个标记, strtok 函数将保存它在字符串 中的位置。strtok 函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。如果字符串中不存在更多的标记,则返回 NULL 指针。
如果我们有这样一个字符数组
char ch[ ] = "abcdefgh.ijk";
我想要拿到abc,用数组也可以达到我们预想的效果,用strtok也可以拿到,上代码:
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- char ch[] = "abcdefgh.ijk";
- char buff[200];
- srtcpy(buff, ch);
- const char* p = ".";//可以作为分割符的字符的集合,可以是多个
- strtok(buff,p);//这个函数就是一个分割符,把我们的字符串分割成n段
- //该函数每次找到p中的其中一个字符(一个标记),就将该字符改成'\0',并返回指向这个标记的指针,这里就是a的地址
- //(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
- //所以我们用另一个字符数组来拷贝ch
-
- return 0;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- char ch[] = "abcdefgh.ijk";
- char buff[200];
- strcpy(buff, ch);
- const char* p = ".";
- char* str = strtok(buff, p);//strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。
- printf("%s\n", str);
- char* str1 = strtok(NULL, p);//第二次使用时保存了上一次使用保存好的位置开始继续查找,然后返回这个字段的启示位置。
- printf("%s\n", str1);
- return 0;
- }
结果如下:
解释 errnum 的值,生成一个字符串,其中包含一条消息,该消息描述错误条件,就好像库的函数设置为 errno 一样。
返回的指针指向静态分配的字符串,程序不得修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)。
拿计算机跑一跑:
我们传参 0 1 2 3 4都有自己的意义。这里的0 1 2 3 4 都是错误码,比如浏览网站时会看见 404 等。
这里有很多经常使用的库函数:
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
|
任何可打印字符,包括图形字符和空白字符
|
mem —> memory 记忆,但是在我们计算机语言中一般翻译为内存。
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到 '\0' 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的。
它和strcpy很像,但是不一样。我们strcpy只能拷贝字符串,我们看memcpy的参数,都是void*型的,所以我们可以是任意类型。
我们用int类型试一试:
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- int arr1[] = { 0,1,2,3,4,5,6,7,8,9 };
- int arr2[10];
- memcpy(arr2, arr1, 40);
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", arr2[i]);
- }
- return 0;
- }
memcpy第三个参数的单位是字节,所以我这里写的是40。
将数字字节的值从源指向的位置复制到目标所指向的内存块。复制就像使用了中间缓冲区一样进行,从而允许目标和源重叠。
源指针和目标指针所指向的对象的基础类型与此函数无关;结果是数据的二进制副本。
该函数不检查源代码中的任何终止空字符 - 它始终精确复制数字字节。
为避免溢出,目标和源参数所指向的数组大小应至少为数字字节。
可以说memmove是memcpy的一部分。
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- void* my_memcpy(void* dest, void* src, size_t num)
- {
- void* ret = dest;
- assert(dest);
- assert(src);
- while(num--)//这里我们一个字节一个字节的交换
- {
- *(char*)dest = *(char*)src;
- dest = (char*)dest + 1;
- src = (char*)src + 1;
- }
- return ret;
- }
- int main()
- {
- int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
- my_memcpy(arr1+2, arr1, 20);
- int i = 0;
- for (i = 0; i < 10; i++)
- {
- printf("%d ", arr1[i]);
- }
- return 0;
- }
再来看看memmove 的结果:
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
- memmove(arr+2, arr, 20);
- int i = 0;
- for (i = 0; i < 10; i++)
- {
- printf("%d ", arr[i]);
- }
- return 0;
- }
比较从ptr1和ptr2指针开始的num个字节
我们重点来看它的返回值:
对于strcmp相比,memcmp的参数是不固定的,而strcmp的参数都是const chat* 类型。 相比之下memcmp功能更加强大。
我们跑一段代码试试:
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- char buffer1[] = "DWgaOtP12df0";
- char buffer2[] = "DWGAOTP12DF0";
- int n;
- n = memcmp(buffer1, buffer2, sizeof(buffer1));
- if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
- else if (n < 0) printf("'%s' is less than '%s'.\n", buffer1, buffer2);
- else printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
- return 0;
- }
顾名思义memset是内存设置函数,这个函数作为补充,想要了解更多,可以查cplusplus.com
这是未调用memset之前的内存。
这是调用之后的内存。