首页 > 其他分享 >(C语言)常见字符函数和字符串函数(详解)

(C语言)常见字符函数和字符串函数(详解)

时间:2024-06-09 12:29:57浏览次数:12  
标签:const 函数 dest C语言 char int 详解 str 字符串

我们都知道,在C语言里有string.h这个头文件,但是C语言里没有string这个类型。
字符串通常放在常量字符串中或者字符数组中,字符串常量适用于那些对她不做修改的字符串函数。
string.h这个头文件里声明的函数原型也全是针对char数组的种种操作。
直到C++中才出现了string这个类

这篇文章我们就来就整理一下C语言中处理字符、字符串的库函数。

一、字符函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。 这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h

以islower为例

int islower ( int c );

islower 是能够判断参数部分的 c 是否是⼩写字⺟的。 通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。

写 ⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变

 #include <stdio.h>
 #include <ctype.h>
 int main ()
 {
     int i = 0;
     char str[] = "Test String.\n";
     char c;
     while (str[i])
     {
     c = str[i];
     if (islower(c)) 
        c -= 32;
     putchar(c);
     i++;
     }
     return 0;
 }

二、字符串函数

strlen

size_t strlen( const char* str)

 功能:计算字符串长度,不包含’\0’
 返回值:返回字符串的字符数
 说明

 

  • strlen() 函数计算的是字符串的实际长度,遇到第一个’\0’结束;
  • 参数指向的字符串必须以 ’ \0 ‘结束
  • 函数返回值一定是size_t ,是无符号的整形
  • 如果你只定义没有给它赋初值,这个结果是不定的,它会从首地址一直找下去,直到遇到’\0’停止
  • sizeof返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符,strlen()是函数

 strlen的模拟实现

方法一:

int my_strlen(const char * str)
 {
 int count = 0;
 assert(str);
 while(*str)
 {
 count++;
 str++;
 }
 return count;
 }

方法二:

//不能创建临时变量计数器
 
int my_strlen(const char * str)
 {
 assert(str);
 if(*str == '\0')
 return 0;
 else
 return 1+my_strlen(str+1);
}

strcpy

char* strcpy(char* dest,char* src)

 

功 能: 将参数src字符串拷贝至参数dest所指的地址
返回值: 返回参数dest的字符串起始地址
说明:

  • 源字符串必须以’\0’结束
  • 会将源字符串的’\0’拷贝到目标空间
  • 目标空间必须可变
  • 如果参数dest所指的内存空间不够大,可能会造成缓冲溢出的错误情况,在编写程序时需特别留意,或者用strncpy()来取代
  •   会将源字符串中的 '\0' 拷⻉到⽬标空间
  •  ⽬标空间必须⾜够⼤,以确保能存放源字符串。 

strcpy的模拟实现 

 //1.参数顺序
 
//2.函数的功能,停⽌条件
 
//3.assert
 //4.const修饰指针
 
//5.函数返回值
 
//6.题⽬出⾃《⾼质量C/C++编程》书籍最后的试题部分
 
char *my_strcpy(char *dest, const char*src)
 {        
char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 while((*dest++ = *src++))
 {
 ;
 }
 return ret;
}

 strcan

char* strcat(char* dest,const char* src)

功能: 字符串拼接
返回值:返回dest字符串起始地址
说明:

  • 字符串必须以 '\0' 结束。
  • ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
  • ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
  • ⽬标空间必须可修改。 字符串⾃⼰给⾃⼰追加,如何?

strcan模拟实现 

 char *my_strcat(char *dest, const char*src)
 {
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 while(*dest)
 {
 dest++;
 }
 while((*dest++ = *src++))
 {
 ;
 }
 return ret;
}

strcmp

int strcmp (const char* str1,const char* str2)

功能:字符串比较
返回值:若参数s1和s2字符串相同则返回0,s1若大于s2则返回大于0的值,s1若小于s2则返回小于0的值
说明

  • 判断两个字符串大小1)ASII码 2)长度
  • 区分大小写比较的,如果希望不区分大小写进行字符串比较,可以使用strcmp函数

 strcmp的模拟实现

int my_strcmp (const char * str1, const char * str2)
 {
 int ret = 0 ;
 assert(src != NULL);
 assert(dest != NULL);
 while(*str1 == *str2)
 {
 if(*str1 == '\0')
 return 0;
 str1++;
 str2++;
 }
 return *str1-*str2;
}

 strncpy

char * strncat ( char * destination, const char * source, size_t num );

重点:strcpy和strncpy的区别是strncpy可以拷贝soutce的前num个字符到destination里面去

功能:拷贝src字符串的前num个字符至dest
返回值:dest字符串起始地址
说明

  • 如果src字符串长度小于num,则拷贝完字符串后,在目标后追加0,直到num个
  • strncpy不会向dest追加’\0’
  • src和dest所指的内存区域不能重叠,且dest必须有足够的空间放置n个字符

 strncan

char* strcat(char* dest,const char* src)

 

功能:将n个字符追加到字符串结尾,结尾自动加'\0'
返回值:返回dest字符串的起始地址
说明:

  • strncat将会从字符串src的开头拷贝n个字符到dest字符串尾部
  • dest要有足够的空间来容纳要拷贝的字符串
  • 如果n大于字符串src的长度,那么仅将src全部追加到dest的尾部
  • strncat会将dest字符串最后的’\0’覆盖掉,字符追加完成后,再追加’\0’

 以下面代码为例

/* strncat example */
 #include <stdio.h>
 #include <string.h>
 int main ()
 {
 char str1[20];
 char str2[20];
 strcpy (str1,"To be ");
 strcpy (str2,"or not to be");
 strncat (str1, str2, 6);
 printf("%s\n", str1);
 return 0

strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

功能:字符串比较同strcmp相似
返回值:比较num个字符的ASII码值,若参数s1和s2字符串相同则返回0,s1若大于s2则返回大于0的值,s1若小于s2则返回小于0的值
说明:

  • 以ASII码值来比较
  • 如果相比较一个字符串中特定长度的字符可以用strncmp来比较

 strstr

 char* strstr(const char* str,const char* substr)

功能:检索子串在字符串中首次出现的位置
返回值:返回字符串str中第一次出现子串substr的地址;如果没有检索到子串,则返回NULL

 以下面的代码为例

 /* strstr example */
 #include <stdio.h>
 #include <string.h>
 int main ()
 {
 char str[] ="This is a simple string";
 char * pch;
 pch = strstr (str,"simple");
 strncpy (pch,"sample",6);
 printf("%s\n", str);
 return 0;
}

strtok

char * strtok ( char * str, const char * delimiters )

功能:根据分隔符将字符串分隔成一个个片段
返回值:返回下一个分割后的字符串指针,如果已无从分割则返回NULL
说明:

  • sep参数是个字符串,定义了用作分隔符的字符集合
  •  第一个参数指定一个字符串,它包含了一个或者多个由sqp字符串中一个或者多个字符分割的标记
  •  第一次调用时将字符串首地址传进去,之后调用不用传地址,内部会有static函数保存指向地址
  •  分隔符不作为输出内容,只做分界符
  •  当strtok在参数s的字符串中发现到参数sep的分割字符时则会将该字符改为’\0’字符
  •  在第一次调用时,strtok必须赋予参数str字符串,往后的调用则将参数s设置成NULL
  •  strtok会修改原字符串,所以必须放至栈上

 以下面代码演示为例

#include <stdio.h>
 #include <string.h>
 int main()
 {
 char arr[] = "192.168.6.111";
 char* sep = ".";
 char* str = NULL;
 for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
 {
 printf("%s\n", str);
 }
 return 0;
}

strerror

char * strerror ( int errnum );

strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。 在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明 的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动 的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应 的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是 有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。一定要包含头文件<errno.h>

 以下面代码为例

 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
 //我们打印一下0~10的错误信息

 int main()
 {
 int i = 0;
 for (i = 0; i <= 10; i++) {
 printf("%s\n", strerror(i));
 }
 return 0;
}

在Windows的环境+VS2022中显示的错误信息如下

atoi

int atoi(const char* str) 

注意:要包含头文件stdlib.h

功能:将字符串转换成整型
返回值:返回转换后的整型数。如果str不能转换成int或者str为空字符串,那么将返回0
说明:

  • ANSI C规范定义了 stof()、atoi()、atol()、strtod()、strtol()、strtoul()共6个可以将字符串转换为数字的函数,可以对比学习
  • 另外在C99/C++11规范中又新增了5个函数,分别是atoll()、strtof()、strtold()、strtoll()、strtoull()
  • 该函数首先根据需要丢弃任意数量的空格字符(如 ),直到找到第一个非空格字符。然后,从此字符开始,采用可选的初始号或号,后跟尽可能多的以 10 为基数的数字,并将它们解释为数值。
  • 字符串可以在构成整数的字符之后包含其他字符,这些字符将被忽略,并且对此函数的行为没有影响。
  • 如果 中的第一个非空格字符序列不是有效的整数,或者由于空或仅包含空格字符而不存在此类序列,则不执行转换并返回零。

以下面代码为例

#include <stdio.h>      /* printf, fgets */
#include <stdlib.h>     /* atoi */

int main ()
{
  int i;
  char buffer[256];
  printf ("Enter a number: ");
  fgets (buffer, 256, stdin);
  i = atoi (buffer);
  printf ("The value entered is %d. Its double is %d.\n",i,i*2);
  return 0;
}

以上就是C语言中常用的字符和字符串类型的函数,大家可以继续扩展学习更多更有趣更好玩的知识!!!

标签:const,函数,dest,C语言,char,int,详解,str,字符串
From: https://blog.csdn.net/2303_81146519/article/details/139554893

相关文章

  • 【调整堆】(C++ 代码实现 & 注释详解)
     自定义结构体:#definesz105typedefstructnode{ intlength; intl[sz];}SqList; 调整堆的函数:HeapAdjust函数思路说明://目标:将以s为根的子树调整为大根堆//具体操作:将路径上比s大的都往上移动,s往下移动,直到遇到比s还小的,就“放下”svoidHeapAdjust(SqList......
  • 避免内存泄漏:C++ 虚析构函数指南
    C++虚析构函数详解及示例在C++编程中,虚析构函数的使用至关重要,尤其在涉及多态时。以下将解释虚析构函数的作用、在基类中使用虚析构函数的必要性以及纯虚析构函数的定义。1.为什么需要虚析构函数?当基类的析构函数没有被声明为虚函数时,通过基类指针删除派生类对象会导致无......
  • C++ 抽象类与纯虚函数详解:理论与实战
    抽象基类为什么不能创建对象?抽象类是一种特殊的类,它被设计用来作为其他类的基类,不能实例化为对象。以下是关于抽象类和纯虚函数的详细解释:1.抽象类的定义:抽象类:带有纯虚函数的类称为抽象类。抽象类不能实例化对象,只能作为基类被继承。纯虚函数:一种没有实现的虚函数,其定义格......
  • 深入解析C++中自动生成默认构造函数的五种情况
    自动生成默认构造函数的情况以及相关解释在C++中,当一个类没有任何用户定义的构造函数时,编译器会自动为这个类生成一个默认构造函数。以下是具体情况的解释以及示例:1.带有默认构造函数的类成员对象如果一个类没有任何构造函数,但它含有一个成员对象,而该成员对象有默认构造......
  • 为什么C++友元函数必须在类内部声明?解析与案例
    友元函数是C++中独特的编程结构,允许一个非成员函数或者其他类访问另一个类的私有和保护数据成员。友元在很多情况下是非常有用的,比如操作符重载、类间紧密合作等。为什么需要在类内部声明友元函数?访问权限:友元函数需要访问类的私有和保护数据成员。为此,必须在类内部声明,以便......
  • 实验6 C语言结构体、枚举应用编程
    //task4.c#include<stdio.h>#include<stdlib.h>#include<string.h>#defineN10typedefstruct{charisbn[20];//isbn号charname[80];//书名charauthor[80];//作者doublesales_price;//售价int......
  • 判定函数单调性和数列单调性的方法
    判定函数和数列的单调性需要使用不同的方法和工具。以下是判定函数单调性和数列单调性的方法:判定函数单调性的方法Step1:使用导数判定单调性对于一个函数f(x)f(x)f(x),可以通过其导数f′(x)f'(x)f′(x)来判定单调性。如果f′(x)>0f'(x)>0f′(x)>0在某个区间上成立,则......
  • 实验6 C语言结构体、枚举应用编程
    task.1#defineN3//运行程序输入测试时,可以把这个数组改小一些输入测试#include<stdlib.h>typedefstructstudent{intid;//学号charname[20];//姓名charsubject[20];//考试科目doubleperf;//......
  • 表达式求值的相关语法知识(C语言)
    目录整型提升整型提升的意义整型提升规则整型提升实例算术转换赋值转换操作符的属性C语言的语法并不能保证表达式的执行路径唯一!!!问题表达式整型提升        C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整......
  • 淘宝/天猫商品信息获取与搜索优化:详解API接口在商品详情获取与关键字搜索中的应用
    在数字化时代,电商平台的API接口成为了连接商家、开发者与消费者的重要桥梁。淘宝和天猫作为中国领先的电商平台,提供了丰富的API接口,使得商家和开发者能够更加便捷地获取商品信息和实现商品搜索功能。本文将详细介绍淘宝/天猫的商品详情API接口和按关键字搜索商品API接口,探讨如......