我们都知道,在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