1. strtok():以分割符分割字符串的函数
它会直接改变字符串内容,直接以分割符切割,把分隔符换为\0。所以一般操作都是对临时拷贝的内容做修改。
第一次调用,strtok()必须给参数s字符串,即对谁分割,往后将S设置为NULL,每次调用成功会返回指定被分割出片段的指针,它每次分割都会记录上次分割到了哪里,即给\0的位置。
利用for的巧妙写法:
int main()
{
char arr[] = "liuzheng@123.net";
char buf[30] = { 0 };
const char* sep = "@.";
strcpy(buf, arr);
char* str = NULL;
for (str = strtok(buf, sep); str != NULL; str = strtok(NULL, sep))
{
printf("%s\n", str);
}
return 0;
}
有人的疑问:它第n次调用,如何知道上次切割在哪儿,且为什么函数调用完释放了内存空间,还能找到上次的值?
它在内部创建了静态变量
2. strerror()返回错误信息库的函数
strerror(i):给不同码,对应不同错误信息
函数哪里执行出错,会把错误码放到全局变量errno错误码中,通过strerror(errno)可以拿到错误信息。
- perror(”mystring“) 插入: 报错时会报你的字符串加系统对应错误
库中还有很多控制大小写,标点符号、图形字符的函数
putchar()打印字符 toupper()转为大写,tolower()转为小写
内存操作函数===
memcpy() 内存拷贝
· memcpy():(void* dest, const void* src, size_t count): void* 因为不知道拷贝的类型是什么,拷贝多少字节由于count参数决定
和strcpy()的区别就是这个可以拷贝任何类型,而strcpy()只能拷贝string
void* my_memcpy(void* dest, const void* src, size_t count)
{
assert(dest && src);
void* ret = dest;
while (count--)
{
// 无类型的指针先强制转换,再解引用成char接收
*(char*)dest = *(char*)src;
dest = (char*)dest+1;
src = (char*)src + 1;
}
return ret;
}
缺点是:不能把自己的内容拷贝给自己,因为这种实现方式,你把自己前面的字符串给后面的过程中,可能后面的字符就已经被覆盖掉了。
memmove()重叠内存拷贝,*自己拷贝给自己
- 自己实现memmove(),主要需要考虑重叠的部分
拷贝部分dest和src位于不同位置,拷贝顺序也不同,如果全部按从前往后害怕后面需要拷贝的字符被前面的覆盖
拷贝顺序如下图示,src拷贝至dest
void* mymemmove(void* dest, const void*src, size_t count)
{
assert(dest && src);
void* ret = dest;
if(dest<src) // dest在左边,它的尾是src头,src头部先做赋值,就不会丢失,按src->顺序
{
// src前到后拷贝给dest
while (count--) // count是字节数,如果要拷贝4个整形,count会给20
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
// dest在src右边,即使要重合,但是重合部分是src的尾,按src -> 会让src的尾字符串丢失,按<-即可
else
{
// 很巧妙的写法,不必在外面先赋值让各自指向最后
while (count--)
{
*((char*)dest+count) = *((char*)src+count);
}
}
return ret;
}
int main()
{
int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// 自己给自己赋值
mymemmove(arr1 + 2, arr1, 20);
int i = 0;
int sz = sizeof(arr1) / sizeof(arr1[10]);
for (i = 0;i<sz; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
注意函数中,void 任意类型的函数,返回任意类型的ret,*
memcmp():可选择字节数做字典序比较
前面一样,但是后面第二个更大,返回-1
memset():以字节为单位设置内容
查看内存情况,&arr位置前20个全设置为0,不是把数组每个元素设0,而以字节为单位设置值