字符函数和字符串函数,超详细!!!

一:字符分类函数

在 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 );

注意:

  1. 空字符结束:确保传递给 strlen 的字符串是以空字符 '\0' 结尾的。如果不是,strlen 可能会读取超出字符串实际长度的内存,导致未定义行为。

  2. 非空指针:不要传递 NULL 指针给 strlen 函数,因为这将导致未定义行为。在调用 strlen 之前,应该检查指针是否非空。

  3. 只计算可见字符strlen 计算的是字符串中可见字符的数量,不包括结尾的空字符 \0

  4. 函数的返回值为size_t,是⽆符号的( 易错 )

  5. 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 是 NULLstrtok 会继续从上次找到的终止字符之后的位置开始处理字符串。
  • 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;
}

  1. 如果 str 参数不为 NULL,则将 lasts 设置为 str 的位置,这是第一次调用时的行为。
  2. 跳过所有在 delim 中的分隔符。
  3. 查找下一个分隔符,将找到的标记的末尾设置为 '\0'
  4. 更新 lasts 指针,以便下一次调用 my_strtok 时可以从上次停止的地方继续。
  5. 返回指向当前标记的指针。

 七: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;

  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值