萌新的学习笔记,写错了恳请斧正。
目录
字符分类函数
在ctype.h头文件中有一些用于字符分类的函数,用于判断字符属于哪种类型
其中常见的有:
- iscntrl:任意控制字符
- isspace:空白字符:空格、换页(\f)、换行(\n)、回车(\t、制表符\t\v
- isdigit:十进制数字0~9
- isxdigit:十六进制数字0~9、a~f、A~F
- islower:小写字母a~z
- isupper:大写字母A~Z
- isalpha:字母a~z或A~Z
- isalnum:字母或数字
- ispunct:标点符号
- isgraph:图形字符
- isprint:任何可打印字符,包括图形字符和空白字符
这些函数如果判断为假,则返回0,否则返回非零
比方说可以写一个识别小写字母并转换为大写的函数:
#include <stdio.h>
#include <ctype.h>
char* caps(char* s)
{
char* ret = s;
do
{
if (islower(*s))
*s -= 32;
} while (*s++);
return ret;
}
int main()
{
char s[] = "ajiofe";
printf("%s", caps(s));
return 0;
}
字符转换函数
其实ctype.h头文件中其实已经内置了可以用于大小写转换的函数,即字符转换函数
其中就包括tolower和toupper,所以上述代码也可以改为:
#include <stdio.h>
#include <ctype.h>
char* caps(char* s)
{
char* ret = s;
do
{
if (islower(*s))
*s = toupper(*s);
} while (*s++);
return ret;
}
int main()
{
char s[] = "ajiofe";
printf("%s", caps(s));
return 0;
}
其实并没有方便多少,感觉用处不大
strlen
#include <string.h>
size_t strlen(const char* str);
strlen用于计算字符串的长度,其返回值size_t是无符号整数
strlen函数将会返回从传递给它的指针开始直到第一个“\0”为止的非零元素的数量
使用strlen函数需要先包含string.h头文件
模拟实现
最简单的就是循环计数了:
#include <stdio.h>
#include <assert.h>
size_t my_strlen(const char arr[])
{
assert(arr);
int i = 0;
while (*(arr + i))
i++;
return i;
}
当然如果使用递归也可以不用循环计数:
size_t my_strlen(const char arr[])
{
assert(arr);
return *(arr) ? 1 + my_strlen(arr + 1) : 0;
}
双指针也可以实现:
size_t my_strlen(const char arr[])
{
assert(arr);
char* p = arr;
while (*p)
p++;
return p - arr;
}
strcpy
#include <string.h>
char* strcpy(char* dest, const char* src);
strcpy用于复制字符串,使用需要先包含string.h头文件
strcpy将从src指针头开始直到‘\0’结尾的部分复制到dest指针指向的地方
注意:
- ‘\0’也会被复制过去
- 目标空间可用部分需要足够大
- 目标空间应当可修改
模拟实现
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++);
return ret;
}
strcat
#include <string.h>
char* strcat(char* dest, const char* src);
strcat用于字符串的追加,使用需要先包含string.h头文件
strcat将从dest指向的位置开始寻找,直到找到‘\0’,然后将从src指向的位置开始到第一个‘\0’为止的部分复制到‘\0’的位置(包括‘\0’)
注意:
- 目标字符串也需要有‘\0’
- 目标空间可用部分需要足够大
- 目标空间应当可修改
- 自己追加自己会造成死循环
模拟实现
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*++dest);
while (*dest++ = *src++);
return dest;
}
strcmp
#include <string.h>
int strcmp(const char* str1, const char* str2);
strcmp用于字符串之间的比较(逐字符),使用需要先包含string.h头文件
strcmp会分别从str1与str2指向的位置开始对比ASCII码值,如果有一方先出现不等情况。则按照规定输出(str1大于str2输出正数,反正负数,如果直到两边都遇到‘\0’都没有不等的情况则输出0)
常用于按字母排序
模拟实现
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (!*str1)
return 0;
str1++, str2++;
}
return *str1 - *str2;
}
strncpy
#include <string.h>
char* strncpy(char* dest, const char* src, size_t n);
strncpy与strcpy功能一致,但是只复制前n个字符(如果位数足够最后不补0)
如果先碰到‘\0’则后续一直补0直到满足n个字符的要求
模拟实现
char* my_strncpy(char* dest, const char* src, size_t n)
{
assert(dest && src);
char* ret = dest;
while (n-- && *src)
*dest++ = *src++;
while (n--)
*dest++ = 0;
return ret;
}
strncat
#include <string.h>
char* strncat(char* dest, const char* src, size_t n);
同样的,是拼接前n个字符,但是会追加一个‘/0’
如果先遇到‘\0’则停止拼接,不需要补0
模拟实现
char* my_strncat(char* dest, const char* src, size_t n)
{
assert(dest && src);
char* ret = dest;
while (*++dest);
while (n--)
{
if (0 == *src)
break;
else
*dest++ = *src++;
}
*dest = 0;
return ret;
}
strncmp
#include <string.h>
int strncmp(const char* str1, const char* str2, size_t n);
同样的,比较前n个字符,比较方法同strcmp
strstr
#include <string.h>
char* strstr(const char* str1, const char* str2);
strstr用于寻找字符串的子序列
strstr会从str1指向的位置开始,寻找第一个与str2相同的序列,并返回找到的序列头的地址
如果没有与str2相同的子序列,则返回空指针NULL
模拟实现
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
char* sign1 = (char*)str1;
char* sign2 = (char*)str1;
char* sign = (char*)str2;
while (*sign1)
{
if (!*sign)
return sign1;
sign1++;
sign2 = sign1;
sign = (char*)str2;
while (*sign2 && *sign && !(*sign2 - *sign))
sign2++, sign++;
}
return NULL;
}
strtok
#include <string.h>
char* strtok(char* str, const char* sep);
strtok用于分割字符串
sep参数指向一个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的非空子串
- 如果str不为NULL,strtok函数找到str中的第一个被分割的子串,并将其用‘\0’结尾(覆盖后面的分隔符),返回一个指向这个子串头的指针
- 如果str为NULL,strtok函数会从上一次使用该函数分割的位置开始,寻找下一个被分割的子串,并将其用‘\0’结尾(覆盖后面的分隔符),返回一个指向这个子串头的指针
- 如果已经分割完了,没有什么能返回的了,就返回NULL
注意!!!strtok会改变原字符串!!!
使用实例
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "192.168.0.1:23333";
char* sep = ".:";
char* str = NULL;
for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
printf("%s\n", str);
return 0;
}
strerror与perror
#include <string.h>
char* strerror(int errnum);
#include <stdio.h> //or <stdlib.h>
void perror( const char *string );
strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回
在不同的系统和C语言标准库的实现中都规定了一些错误码,一般在errno.h头文件中说明
程序启动的时候就会使用一个全局变量errno来记录程序的当前错误码(初始为0表示无错)
使用实例
#include <stdio.h>
#include <string.h>
int main()
{
int i = 0;
for (i = 0; i < 44; i++)
printf("%s\n", strerror(i));
return 0;
}
而perror函数则进一步,可以直接打印“输入的字符串+冒号+错误信息”一条龙。