**
对字符串函数的使用和理解(2)
笔记来了
续上次之后的还有:
长度受限制的字符串函数: 1,strncpy 2,strncat 3,strncmp;
内存操作函数:1,memcpy 2,memmove 3,memset 4,memcmp;
字符串查找:1,strstr 2,strtok;
错误信息报告: strerror
1、长度受限制的字符串函数
strncpy函数原型为:
char * strncpy ( char * destination, const char * source, size_t num );
一眼望去,咦~,比之前的strcpy函数原型多了个参数耶,没差了,其实相对与无长度受限,这里只需要设置想要控制的个数(单位:字节)。
举个例子吧:
char * my_strncpy(char *dest, const char *str,size_t count)
{
assert(dest && str); //确保指针的有效性(这点是跟B站的鹏哥学的)
char* ret = dest;
while (count && (*dest++ = *str++))
count--;
if (count)
while (--count)
*dest++ = '\0';
return ret;
}
int main()
{
char arr1[10] = "hello";
char arr2[] = "world";
// strncpy(arr1, arr2,4); //第三个参数是字节个数,arr1为源字符串;当arr2指定的个数远比字符串"world"多时,自动补‘\0’
//如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后面追加0,直到num个
my_strncpy(arr1, arr2,4); //自定义实现函数
printf("%s\n", arr1);
return 0;
});
相对比较之前的来看,其实大致都是一样的格式,只不过,在操作字符串的时候差不多都要和字符串后面隐含的‘\0’打交道。
对于后两个就不多说,直接上例子:
strncat 字符串追加原型:
char * strncat ( char * destination, const char * source, size_t num );
自定义实现函数:
char * my_strncat(char *dest, const char *str,size_t count)
{
assert(dest && str);
char* ret = dest;
while (*dest++)
;
dest--;
while (count--)
if(!(*dest++ = *str++))
return ret;
*dest = '\0';
return ret;
}
int main()
{
char arr1[20] = "hello\0abcd";
char arr2[] = "world";
//strncat(arr1, arr2,4); //第三个参数是追加的字符串数,arr1为源字符串;arr2追加4个字符串,没有超过 "world"字符串的长度,只在arr1的\0后加4个字符串为:"helloworl",
//假如追加个数超出了字符串arr2的个数,只会将全部字符串"world"追加过去(带\0),不会再多余补\0
my_strncat(arr1, arr2,4); //自定义函数
printf("%s\n", arr1);
return 0;
}
strncmp字符串比较 ,ASCII值大小比较;
原型函数为
int strncmp ( const char * str1, const char * str2, size_t num );
针对字符串查找:
------------------------strstr查找字符串-------------------------------------
//原型:const char * strstr ( const char * str1, const char * str2 );
char * strstr(char * str1, const char * str2);
//这个例子在str中搜索“simple”子字符串并将其替换为“sample”。
int main ()
{
char str[] = "This is a simple string";
char * pch;
pch = strstr(str, "simple");
if (pch != NULL)
strncpy(pch, "sample", 6);
printf("%s\n",str); //输出 This is a sample string
return 0;
}
关于内存操作函数:
----------------------memcpy内存拷贝--------------------------------
//原型:void * memcpy ( void * destination, const void * source, size_t num ); 第三个参数是设置要拷贝多少个字节
//自己实现一个内存拷贝函数
struct s
{
char name[20];
int age;
};
void * my_memcpy(void * destination, const void * source, size_t num)
{
assert(destination && source);
char* ret = destination;
while (num--)
{
*(char*)destination = *(char*)source;
++(char*)destination; //先进行数据转换,再++
++(char*)source;
}
return ret;
}
int main()
{
struct s arr1[] = { {"zhangsan",20},{"lisi",30} };
struct s arr2[4] = { 0 };
my_memcpy(arr2, arr1, sizeof(arr1)); //将arr1里面的内容完全拷贝到arr2中去。
return 0;
}
需要注意的是:C语言规定memcpy只要处理内存不重叠的就可以了,
memmove函数处理内存重叠的情况拷贝。
自己定义memmove函数:
void * my_memcpy(void * destination, const void * source, size_t num)
{
char* ret = destination;
assert(destination && source);
if (destination < source)
{
//从前到后
while (num--)
{
*(char*)destination = *(char*)source;
++(char*)destination; //先进行数据转换,再++
++(char*)source;
}
}
else
{
//从后到前
while (num--)
*((char*)destination +num) = *((char*)source+num);
}
return ret;
}
memset//内存设置,这个函数 的作用是在一段内存块中填充某个给定的值。因为它只能填充一个值,所以该函数的初始化为原始初始化,无法将变量初始化为程序中需要的数据。用memset初始化完后,后面程序中再向该内存空间中存放需要的数据。更改的单位是字节
例:
int main()
{
int arr[10] = { 0 };
memset(arr,'#',10);//将arr数组的10个字节改成字符'#'
int arr1[10] = { 0 };
memset(arr1, 1, 10); //这个容易产生错误,因为是int类型的数组,而这句只改了前10个字节,但整个数组有40个字节,实际上只改成了:
//01 01 01 01 01 01 01 01 01 00 00 (前两个int类型).....00
return 0;
}
对于这些函数,其实只是想要知道怎么使用的话,查找函数的使用规则就好了,网上都是一大堆。但是想要自己写出来一个自定义的函数,那就要对这个函数充分的理解,和一定的思维能力,当然,也有低版本的VS编译器,有提供源代码哦,但是VS17找源代码找起来就比较费劲了。
这些函数参考下面这个网址使用吧~:
http://www.cplusplus.com/