上章我们简单介绍了几个字符串函数,这里先补充几个。
嘿咻咻咻咻咻,鸡汤来咯。
目录
1.strtok
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;
}
结果如下:
2. strerror

解释 errnum 的值,生成一个字符串,其中包含一条消息,该消息描述错误条件,就好像库的函数设置为 errno 一样。
返回的指针指向静态分配的字符串,程序不得修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)。
拿计算机跑一跑:
我们传参 0 1 2 3 4都有自己的意义。这里的0 1 2 3 4 都是错误码,比如浏览网站时会看见 404 等。
3.字符分类函数:
这里有很多经常使用的库函数:
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
|
任何可打印字符,包括图形字符和空白字符
|
4.内存函数
4.1memcpy
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。
4.2 memmove
将数字字节的值从源指向的位置复制到目标所指向的内存块。复制就像使用了中间缓冲区一样进行,从而允许目标和源重叠。
源指针和目标指针所指向的对象的基础类型与此函数无关;结果是数据的二进制副本。
该函数不检查源代码中的任何终止空字符 - 它始终精确复制数字字节。
为避免溢出,目标和源参数所指向的数组大小应至少为数字字节。
可以说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;
}
4.3memcmp
比较从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;
}
4.4 memset
顾名思义memset是内存设置函数,这个函数作为补充,想要了解更多,可以查cplusplus.com
这是未调用memset之前的内存。
这是调用之后的内存。