一:字符分类函数
在 C 语言中,字符分类函数通常用于判断字符是否属于某种特定的类型(如字母、数字、空白等)。这些函数通常在 <ctype.h>
头文件中声明
二:字符转换函数
int toupper (int c)//将参数传进去的小写字母转换为大写字母;
int tolower (int c)//将参数传进去的大写字母转换为小写字母;
举例:小写转化为大写:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main()
{
char a[] = "du jie shi ge da shuai bi";
int len = strlen(a);
for (int i = 0; i < len;i++)
{if (islower(a[i]))//如果a[i]是小写,则返回非0的数;
a[i]=toupper(a[i]);将小写的a[i]改为大写;
//方法二://if(a[i]>'a'&&a[i]<'z') a[i]=a[i]-32;因为大写字母的ascall码是小写-32;
}
printf("%s", a);
return 0;
}
三:strlen函数及其实现方法
函数定义:返回 字符串 str 的长度;
size_t strlen ( const char * str );
注意:
空字符结束:确保传递给
strlen
的字符串是以空字符'\0'
结尾的。如果不是,strlen
可能会读取超出字符串实际长度的内存,导致未定义行为。非空指针:不要传递
NULL
指针给strlen
函数,因为这将导致未定义行为。在调用strlen
之前,应该检查指针是否非空。只计算可见字符:
strlen
计算的是字符串中可见字符的数量,不包括结尾的空字符\0
函数的返回值为size_t,是⽆符号的( 易错 )
strlen的使⽤需要包含头⽂件string.h
例:
#include<stdio.h>
int main()
{
if(strlen("abcd")-strlen("abcdef")>0)//4-6
printf(">");
else printf("<")
}
你认为是输出<么?结果是>,因为strlen返回值是size-t类型,为无符号数,得到的-2补码中的符号位不计,当作很大的一个数字。
strlen 函数实现方法
方式一://指针-指针的⽅式//得到的是首尾指针之间元素个数
size_t my_strlen(const char *s)
{
assert(str);//避免为空
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
方式二:递归
size_t my_strlen(const char * str)
{
assert(str);//避免str为空
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}
四:strcpy函数及其实现方法
strcpy
是 C 和 C++ 编程语言中的一个标准库函数,用于复制字符串。它将源字符串(包括结尾的空字符'\0'
)复制到目标缓冲区。这个函数定义在<string.h>
头文件中
函数原型:char *strcpy(char *dest, const char *src);
dest
:指向目标缓冲区的指针,该缓冲区必须足够大,以便容纳源字符串的副本以及结尾的空字符。src
:指向要复制的源字符串的指针。必须以\0结尾- 返回值:返回一个指向目标字符串
dest
的指针。- 目标空间必须可以修改//不能指向例如 char a=“abcd”的常量字符串,因为该空间不可被修改,一般指向字符数组;
strcpy
会覆盖目标缓冲区中的任何现有数据,所以使用前确保不会覆盖重要的数据源字符串的非空:不要传递
NULL
指针给src
参数,这会导致未定义行为。
strcpy
会复制源字符串中的所有字符,包括结尾的空字符'\0'
使用案例:
#include <stdio.h>
#include <string.h>int main() {
// 声明两个字符数组,一个用于源字符串,一个用于目标字符串
char source[] = "Sample string.";
char destination[20]; // 确保这个数组足够大,以容纳源字符串和空字符// 使用 strcpy 函数复制字符串
strcpy(destination, source);// 打印复制的字符串
printf("The destination string is: '%s'\n", destination);return 0;
}
函数实现方法:
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;//将首地址先存储起来
assert(dest != NULL);//避免为空
assert(src != NULL);
while((*dest++ = *src++));//逐字符复制,包括\0;
return ret;//返回首地址
}
五:strcat函数及其实现方法
strcat
是 C 和 C++ 编程语言中的一个标准库函数,用于将源字符串连接到目标字符串的末尾。在连接字符串时,strcat
会覆盖目标字符串末尾的空字符'\0'
,并在连接后的字符串末尾添加一个新的空字符。这个函数定义在<string.h>
头文件中
函数原型:char *strcat(char *dest, const char *src);
dest
:指向目标字符串的指针,该字符串必须足够大,以便容纳连接后的字符串(包括结尾的空字符)。src
:指向要连接的源字符串的指针。- 返回值:返回一个指向目标字符串
dest
的指针。- 注意:
源字符串必须以 '\0' 结束。
• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
• ⽬标空间必须可修改。//不要指向常量字符串!
使用案例:
#include <stdio.h>
#include <string.h>int main() {
char dest[50] = "Hello, "; // 确保这个数组足够大
const char *src = "World!";strcat(dest, src); // 连接字符串
printf("The concatenated string is: %s\n", dest);
return 0;
}
输出结果:The concatenated string is: Hello, World!
函数实现:
char *my_strcat(char *dest, const char*src)
{
char *ret = dest;//存储首地址
assert(dest != NULL);//确保非空
assert(src != NULL);
while(*dest) dest++;找到\0的位置
while((*dest++ = *src++));从\0位置开始逐个复制;
return ret;
}
五:strstr函数及其实现方法
strstr:
其功能是在一个字符串(称为haystack)中查找另一个字符串(称为needle)的第一个出现位置。如果找到了子串,
strstr
返回指向子串在原字符串中位置的指针;如果没有找到,则返回NULL。
函数原型如下:char *strstr(const char *haystack, const char *needle);
参数说明:
haystack
:指向要搜索的字符串的指针。needle
:指向要查找的子串的指针。- 注意:
空指针检查:在使用
strstr
之前,应确保haystack
和needle
不是空指针,以避免程序崩溃。空字符串
needle
:如果needle
是一个空字符串,strstr
的行为是未定义的。在一些实现中,它可能会返回haystack
,在其他实现中可能会返回NULL
或引发其他行为。返回值:如果
strstr
找到了子串,它返回一个指向子串在原字符串中首次出现位置的指针。如果没有找到子串,则返回NULL
。不要对返回的NULL
指针进行解引用操作。
示例:
#include <stdio.h>
#include <string.h>int main() {
const char haystack[20] = "Hello World";
const char needle[10] = "World";char *ptr = strstr(haystack, needle);
if (ptr) {
printf("子串 '%s' 在原字符串中首次出现的位置是:'%s'\n", needle, ptr);
} else {
printf("未找到子串 '%s'。\n", needle);
}return 0;
}
子串 'World' 在原字符串中首次出现的位置是:'World'
实现方法:
char* mystr(const char* s1, const char* s2)
{
const char* cur = s1;
const char* s11 = s1;
const char* s22 = s2;
while (*cur != '\0')
{
s11 = cur;//每次匹配失败从cur位置重新挨个依次开始匹配
s22 = s2;//每次匹配失败则重新从头开始匹配
while (*s11 != '\0' && *s22 != '\0' && *s11 == *s22)
{
s11++;//匹配成功一个字母,继续匹配
s22++;
}
if (*s22 == '\0')return (char*)cur;//匹配成功
cur++;//每次匹配失败时起始匹配指针移动一位
}
return 0;//没找到匹配项}
int main()
{
const char* s1 = "abcd";
const char* s2 = "abd";
char* ret=mystr(s1, s2);
printf("%s", ret);}
六: strtok函数及其实现方法:
strtok
是 C 语言标准库中的一个函数,用于将字符串分割成一系列的标记(tokens)。strtok
在<string.h>
头文件中定义。它使用一个或多个分隔符来标识字符串中的标记边界。
函数原型:char *strtok(char *str, const char *delim);
参数说明:
str
:指向要分割的字符串的指针。在第一次调用strtok
时,这个参数应该指向要处理的字符串。在随后的调用中,应该传递NULL
,以便strtok
继续处理之前的字符串。delim
:一个包含分隔符字符的字符串。
strtok
的工作原理如下:- 在第一次调用时,
strtok
查找str
中第一个不包含在delim
中的字符。- 然后,
strtok
标记从这个字符开始的子字符串,并在遇到delim
中任意字符时终止。- 终止字符被替换为 null 字符 (
'\0'
),并且strtok
返回指向标记的指针。- 在后续调用中,如果
str
是NULL
,strtok
会继续从上次找到的终止字符之后的位置开始处理字符串。- strtok函数会改变原有字符串,因为会增添\0;所以我们一般临时拷贝了该字符串后再使用它
举例:
char s1[]="3036868647@qq.com"
char s2[]="@."
第一次调用时:printf("%s",strstr(s1,s2))//打印结果:3036868647,strstr函数首先将@改为\0并暗自记录该标记位置,即@字符的位置,然后返回这段标记的起始地址即3;
第二次调用时:printf("%s",strstr(NULL,s2))//打印结果:qq,strstr函数从上回记录的地址@开始走,然后到达第二个标记‘.’之后将‘.’改为\0并暗自记录'.'的位置,然后返回这段标记的其实地址即q;
第三次调用时:printf("%s",strstr(NULL,s2))//打印结果:com,strstr函数从上回记录的地址'.'开始走,后面没有标记了,即达到末尾,然后就打印该段;
当然,在实际情况中,我们可能并不知道一个字符串有多少个标记,我们可以给出标记有哪些,通过循环,让他自动找出来,例如
int main()
{char s[] = "3036868647@qq.com"; char s2[] = "@.";
for (char* i = strtok(s, s2); i != NULL; i = strtok(NULL, s2))//i为strtok函数得到的起始地址,只要得到的地址不为空,(strtok找不到标识符后返回NULL),就会继续查找;
{ printf("%s\n", i); }
}
或者
#include <stdio.h>
#include <string.h>int main() {
char str[] = "This is a sample string";
const char *delimiters = " ";
char *token;/* 获取第一个标记 */
token = strtok(str, delimiters);/* 继续获取剩余的标记 */
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, delimiters);
}return 0;
}
模拟实现:
#include <stdio.h>
#include <string.h>// 模拟实现 strtok
char *my_strtok(char *str, const char *delim) {
static char *lasts; // 静态变量,保存上一次的位置
char *token;// 第一次调用时,使用传入的字符串
if (str != NULL) {
lasts = str;
}// 检查是否已经到达字符串末尾
if (lasts == NULL || *lasts == '\0') {
return NULL;
}// 跳过字符串开头的所有分隔符
while (*lasts && strchr(delim, *lasts)) {
lasts++;
}// 如果已经到达字符串末尾,返回 NULL
if (*lasts == '\0') {
return NULL;
}// 标记开始位置
token = lasts;// 找到下一个分隔符
while (*lasts && !strchr(delim, *lasts)) {
lasts++;
}// 如果找到分隔符,将其替换为 '\0' 并更新位置
if (*lasts) {
*lasts = '\0';
lasts++;
}return token;
}int main() {
char str[] = "This is a sample string";
const char *delimiters = " ";
char *token;// 获取第一个标记
token = my_strtok(str, delimiters);// 继续获取剩余的标记
while (token != NULL) {
printf("%s\n", token);
token = my_strtok(NULL, delimiters); // 继续分割
}return 0;
}
- 如果
str
参数不为NULL
,则将lasts
设置为str
的位置,这是第一次调用时的行为。- 跳过所有在
delim
中的分隔符。- 查找下一个分隔符,将找到的标记的末尾设置为
'\0'
。- 更新
lasts
指针,以便下一次调用my_strtok
时可以从上次停止的地方继续。- 返回指向当前标记的指针。
七:strerror函数:
strerror
是 C 语言标准库中的一个函数,它用于将错误编号转换为易读的错误消息字符串。
函数原型:char *strerror(int errnum);
参数说明:
errnum
:一个整数,表示错误编号。通常,这是errno
变量的值,errno
是在<errno.h>
中定义的全局变量,它包含了最后一个系统调用或库函数调用的错误编号。-
在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会将对应的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是有对应的错误信息。strerror函数就可以将错误对应的错误信息字符串的地址返回。
例如,打印0-9的错误信息
int main()
{
int i = 0;
for (int i = 0; i < 10; i++)
{
printf("%d\t%s\n", i, strerror(i));
}return0;
}
应用:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
FILE * pFile;
pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("Error opening file unexist.ent: %s\n", strerror(errno));//文件打开失败时,会将错误码存储在errno中,此时打印该结果可以知道程序哪里错了;
return 0;
}