C-字符(串)函数及内存函数-创新互联
目录
创新互联建站一直秉承“诚信做人,踏实做事”的原则,不欺瞒客户,是我们最起码的底线! 以服务为基础,以质量求生存,以技术求发展,成交一个客户多一个朋友!为您提供成都做网站、成都网站制作、成都外贸网站建设、成都网页设计、微信小程序开发、成都网站开发、成都网站制作、成都软件开发、重庆App定制开发是成都本地专业的网站建设和网站设计公司,等你一起来见证!求字符串长度
头文件
strlen - 计算字符串长度
函数声明
strlen 函数模拟
PS.strlen计算出来的为无符号数,两个无符号数进行运算恒为正
长度不受限制的字符串函数
头文件
PS.此类函数只关注 '\0',使用时可能会越界访问
strcpy - 字符串拷贝
函数声明
strcpy 函数模拟
strcat - 字符串追加
函数声明
strcat 发生C4996错误解决
strcat 函数模拟
strcmp - 字符串比较
函数声明
strcmp 函数模拟
长度受限制的字符串函数
头文件
strncpy - 字符串拷贝
函数声明
strncat - 字符串追加
函数声明
strncmp - 字符串比较
函数声明
查找字符串
头文件
strstr - 查找字符串
函数声明
PS.NULL/null - 空指针 NUL/Null - '\0'
strstr 函数模拟
strtok - 拆解字符串
函数声明
字符串报错
头文件
strerror - 错误报告
函数声明
字符分类函数
头文件
字符转换函数
头文件
内存函数
头文件
memcpy - 拷贝函数
函数声明
memcpy 函数模拟(不包括内存重叠的情况)
memmove - 处理重叠拷贝函数
函数声明
memmove 函数模拟
memcmp - 比较函数
函数声明
memset - 内存设置函数
函数声明
求字符串长度 头文件
#include
strlen - 计算字符串长度
函数声明size_t strlen (const char* str); //size_t == unsigned int
字符串以 '\0' 作为结束标志,strlen 函数返回的是在字符串中 '\0' 前面出现的字符个数
参数指向的字符串要以 '\0' 结束
#includeint main()
{
char arr[] = { 'a','b','c' };
//在后面加入'\0'时,就不会计算成随机值了
//即:{ 'a','b','c','\0' }
int len = strlen(arr);
printf("%d", len);
return 0;
}
strlen 函数模拟指针
#include#include
unsigned int strlen_s(char* str)
{ //此处 unsigned int 是符合原函数声明
//写为 int 也可以
int count = 0;
assert(str != NULL);
while (*str != '\0')
{
count++;
str++;
}
return count;
}
递归
#includeint my_strlen(char* str)
{
if (*str != '\0')
{
return 1 + strlen_s(str + 1);
}
else
{
return 0;
}
}
PS.strlen计算出来的为无符号数,两个无符号数进行运算恒为正
长度不受限制的字符串函数
头文件#include
PS.此类函数只关注 '\0',使用时可能会越界访问
strcpy - 字符串拷贝
函数声明char* strcpy(char* destination, const char* source);
destination - 目标数组
source - 起始数组
源字符串中必须要以 '\0' 结束
目标字符串空间要足够大
目标空间大小要可修改
#include#includeint main()
{
char arr1[] = "abcdefg";
char arr2[] = "yes";
strcpy(arr1, arr2);
//拷贝的时候 '\0' 也会拷贝过去
return 0;
}
strcpy 函数模拟#include#include
char* my_strcpy(char* dest, const char* src)
{
assert(dest != NULL);
assert(src != NULL);
char* ret = dest;
//拷贝 src 指向的字符串到 dest
while (*dest++ = *src++)
{
;
}
//返回目的空间的起始地址
return ret;
}
strcat - 字符串追加
函数声明char* strcat(char* destination, const char* source);
追加字符串时是从第一个 '\0' 开始,源字符串中的 '\0' 也会追加过去
目标空间要足够大,能容纳下源字符串的内容
目标空间必须可以修改
字符串自己给自己追加时会出错,程序崩溃
#include#includeint main()
{
char ch1[20] = "Hello";
char ch2[] = "World";
strcat(ch1, ch2);
printf("%s\n", ch1);
return 0;
}
strcat 发生C4996错误解决方法一:项目右键 - 属性 - C/C++ - 预处理器 - 预处理器定义 - 编辑,加上
_CRT_SECURE_NO_DEPRECATE
方法二:在程序最前面加上
#define _CRT_SECURE_NO_WARNINGS
strcat 函数模拟#include#include
char* my_strcat(char* dest, const char* src)
{
assert(dest != NULL);
assert(src != NULL);
//两行代码可缩写为 assert(dest && src);
char* ret = dest;
while (*dest != '\0')
{
dest++;
}
while (*dest++ = *src++)
{
; //追加时的代码和 strcpy 一样
}
return ret;
}
strcmp - 字符串比较
函数声明int strcmp(const char* str1, const char* str2);
str1 >str2,返回值 >0
str1 = str2,返回值 = 0
str1< str2,返回值< 0
比较首字符大小(根据ASCII码表比较),而非字符串长度
当首字符相等时,比较第二位字符,以此类推
#include#includeint main()
{
char* p1 = "abc";
char* p2 = "xyz";
int a = strcmp(p1, p2);
printf("%d\n", a);
return 0; //打印 -1
}
strcmp 函数模拟#include#include
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
if (*str1 >*str2)
return 1;
else
return -1;
}
#include#include
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return (*str1 - *str2);
}
长度受限制的字符串函数
头文件#include
strncpy - 字符串拷贝
函数声明char* strncpy(char* destination, const char* source, size_t count);
strncat - 字符串追加 函数声明count - 拷贝的字节数 - 单位为字节
count 数字如果大于 source 字符个数,不足就补 '\0'
char* strcat(char* destination, const char* source, size_t count);
strncmp - 字符串比较 函数声明count - 追加的字节数 - 单位为字节
int strcmp(const char* str1, const char* str2, size_t count);
查找字符串 头文件count - 比较的字节数 - 单位为字节
如 count = 3,则各自比较前3个字符
#include
strstr - 查找字符串
函数声明char* strstr(const char *haystack, const char *needle);
haystack - 要被检索的字符串
needle - 在 haystack 字符串内要搜索的小字符串
该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回NULL - 空指针
打印时 %p - 找到返回地址,未找到返回NULL
%s - 找到返回需要找的字符串及之后的字符串,未找到返回NULL
PS.NULL/null - 空指针 NUL/Null - '\0' strstr 函数模拟#include#include
char* my_strstr(const char* p1, const char* p2)
{
assert(p1 && p2);
char* s1, * s2;
char* start = p1;
//p1 为 const char* 类型,而 start 为 char* 类型
//此处可将 p1 强制类型转换为 char* 类型
while (*start)
{
s1 = start;
s2 = p2;
while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
{
s1++;
s2++;
}
if (*s2 == '\0')
return start;
if (*s1 == '\0')
return NULL;
start++;
}
return NULL;
}
strtok - 拆解字符串
函数声明char* strtok(char *str, const char *delim);
str - 要被分解成一组小字符串的字符串
delim - 包含分隔符的字符串
该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个NULL - 空指针
strtok 函数会拷贝一份源字符串,对拷贝的字符串进行拆解
- 当 strtok 函数的第一个参数为NULL时,函数将找到 str 中的第一个标记,strtok 函数将保存它在字符串中的位置
- 当 strtok 函数的第一个参数不为NULL时,函数将在刚才的那个字符串中被保存的位置开始查找下一个标记,进行获取第二个、第三个子字符串
- 当字符串中不存在更多的标记,则返回NULL - 空指针
#include#includeint main()
{
char arr[] = "StarDustShakeHand@hotmail.com";
const char* ch = "@.";
char* ret;
for (ret = strtok(arr, ch); ret != NULL; )
{
printf("%s\n", ret);
ret = strtok(NULL, ch);
}
return 0;
}
字符串报错
头文件#include
strerror - 错误报告
函数声明char* strerror(int errnum);
输入错误码,返回错误信息
#include#includeint main()
{
char* str = strerror(0);
printf("%s\n", str);
//打印 No error
return 0;
}
#include#includeint main()
{
char* str = strerror(1);
printf("%s\n", str);
//打印 Operation not permitted
return 0;
}
错误码输入 errno,errno是一个全局的错误码变量,当C语言库函数在执行过程中发生了错误,就会把对应的错误码赋值到 errno 中
字符分类函数 头文件#include
函数 | 参数满足以下条件则返回真 |
iscntrl | 任何控制字符 |
isspace | 空白字符:空格;换页'\f';换行'\n';回车'\r',制表符'\t';垂直制表符'\v' |
isdigit | 十进制数 0 ~ 9 |
isxdigit | 十六进制数 0 ~ 9;A ~ F;a ~ f |
islower | 小写字母 a ~ z |
isupper | 大写字母 A ~ Z |
isalpha | 小写或大写字母 |
isalnum | 字母或十进制数字 |
ispunct | 标点符号,可打印的不属于数字或字母的图形字符 |
isgraph | 任何图形字符 |
isprint | 任何可打印的字符(包括图形、空白字符 |
#include
函数 | 用处 |
tolower | 将小写字符转为大写字符 |
toupper | 将大写字符转为小写字符 |
#include//或者
#include
作用范围比字符串函数大,任何类型的数据都能操作
memcpy - 拷贝函数 函数声明void* memcpy(void* destination, const void* source, size_t num);
- memcpy 函数从 source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置
- 遇到 '\0' 时不会停下
- 当 source 和 destination 有任何的重叠,复制的结果都是未定义的
memcpy 处理内存不重叠的情况就行
memmove 要可以处理内存重叠的情况
#include#includeint main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[5] = { 0 };
memcpy(arr2, arr1, sizeof(arr1));
return 0;
}
#include#includestruct Stu
{
char name[20];
int age;
};
int main()
{
struct Stu arr1[] = { {"小明",18},{"小红",19},{"小刚",20} };
struct Stu arr2[3] = { 0 };
memcpy(arr2, arr1, sizeof(arr1));
return 0;
}
memcpy 函数模拟(不包括内存重叠的情况)#include#include
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest && src);
char* ret = dest;
while (num--)
*((char*)dest)++ = *((char*)src)++;
return ret;
} //dest 会改变,最好还是 void* ret
memmove - 处理重叠拷贝函数
函数声明void* memmove(void* destination, const void* source, size_t num);
可处理内存重叠的情况
memmove 函数模拟#include#include
void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest && src);
void* ret = dest;
if (dest< src)
{
while (num--)
*((char*)dest)++ = *((char*)src)++;
}
else
{
while (num--)
*((char*)dest + num) = *((char*)src + num);
}
return ret;
} //dest 会改变,最好还是 void* ret
memcmp - 比较函数
函数声明int memcmp(const void* ptr1, const void* ptr2, size_t num);
比较从 ptr1 和 ptr2 指针开始的 num 个字节,比出大小时就停止
ptr1 >ptr2,返回值 >0
ptr1 = ptr2,返回值 = 0
ptr1< ptr2,返回值< 0
#include#includeint main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[] = { 1,3,2,4,5,6,7,8,9,10 };
int a = memcmp(arr1, arr2, 5);
//a< 0
return 0;
}
memset - 内存设置函数
函数声明void* memset(void* str, int c, size_t n);
str - 指向要填充的内存块
c - 要被设置的值。该值以 int 形式传递,但在函数中时是使用该值的无符号字符形式
n - 要被设置为该值的字符数 - 单位为字节
#include#includeint main()
{
char arr[10] = "";
memset(arr, '#', 10);
return 0;
}
#include#includeint main()
{
int arr[10] = { 0 };
memset(arr, 1, sizeof(arr));
//元素都变为 16843009,memset 是一个字节一个字节地改
return 0;
}
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
文章名称:C-字符(串)函数及内存函数-创新互联
当前链接:http://scjbc.cn/article/icsoi.html