字符串函数
文章目录
之前已经介绍过了 strlen函数,这篇将介绍剩余的部分字符串函数
1. strcpy(string copy)
1.1 定义
strcpy是一种C语言的标准库函数,strcpy把含有’\0’结束符的字符串复制到另一个地址空间,返回值的类型为char*。
函数的声明
char *strcpy(char *dest, const char *src)
参数
- dest – 指向用于存储复制内容的目标数组。
- src – 要复制的字符串。
返回值
该函数返回一个指向最终的目标字符串 dest 的指针。
功能
把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
说明
src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
1.2 代码实现
/**
* 自己实现strcpy函数
* @param dest 目标地址
* @param src 源数据地址 (为保护数据不被更改,使用常量指针接收)
*/
char *my_strcpy(char *dest, const char *src)
{
char * start=dest;
//防止空地址
assert(dest != NULL);
assert(src != NULL);
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
//最后将'\0'赋给dest
*dest = *src;
return start;
}
/**
* 简化版本
* @param dest
* @param src
*/
char *my_strcpy2(char *dest, const char *src)
{
char * start=dest;
//防止空地址
assert(dest != NULL);
assert(src != NULL);
//依次将src中的每个元素赋给dest,当遇到‘\0’时,将其也赋给src,这时 *dest++ = *src++= 0,刚好结束循环
while ((*dest++ = *src++))
{
}
return start;
}
2. strcmp(string compare)
2.1 定义
比较两个字符串是否相等
声明
下面是 strcmp() 函数的声明。
int strcmp(const char *str1, const char *str2)
参数
- str1 – 要进行比较的第一个字符串。
- str2 – 要进行比较的第二个字符串。
返回值
该函数返回值如下:
- 如果返回值小于 0,则表示 str1 小于 str2。
- 如果返回值大于 0,则表示 str1 大于 str2。
- 如果返回值等于 0,则表示 str1 等于 str2。
2.2 代码实现
/**
* 自定义比较函数
* @param s1 第一个字符串
* @param s2 第一个字符串
* @return
*/
int my_strcmp(const char *s1, const char *s2)
{
//防止空指针
assert(s1);
assert(s2);
//依次判断两个字符串每一个字符是否相等
while (*s1 == *s2)
{
//如果两个字符串同时遇到'\0表示,两个字符串相等
if (*s1 == '\0')
{
//返回0
return 0;
}
//指针后移
s1++;
s2++;
}
//如果遇到不同的字符,比较其对应ASCII码值
//如果前者大于后者,返回正数
/*
if (*s1 > *s2)
{
return 1;
}
//否则返回负数
else
{
return -1;
}
*/
//简化
return *s1 - *s2;
}
3. strcat
3.1 定义
描述
C 库函数 char *strcat(char *dest, const char *src) 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
声明
下面是 strcat() 函数的声明。
char *strcat(char *dest, const char *src)
参数
- dest – 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
- src – 指向要追加的字符串,该字符串不会覆盖目标字符串。
返回值
该函数返回一个指向最终的目标字符串 dest 的指针。
3.2 代码实现
/**
*
* @param dest 第一个字符串位置
* @param src 第二个字符串位置
* @return 第一个字符串位置
*/
char *my_strcat(char *dest, const char *src)
{
assert(dest != NULL);
assert(src != NULL);
char *start = dest;
//找第一个字符串结束标志‘\0’
while (*dest)
{
dest++;
}
//从第一个字符串结束位置开始追加
while ((*dest++ = *src++))
{
}
return start;
}
4. strtok
4.1定义
描述
C 库函数 char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。
声明
下面是 strtok() 函数的声明。
char *strtok(char *str, const char *delim)
参数
- str – 要被分解成一组小字符串的字符串。
- delim – 包含分隔符的 C 字符串。
返回值
该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
说明
strtok函数将字符串分割成一个个片段。参数s指向欲分割的字符串,参数delim则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回指向被分割出片段的指针。
4.2 使用实例
具体代码实现,请参考c标准库,这里只介绍如何使用;
- strtok函数会破坏被分解字符串的完整,调用前和调用后的s已经不一样了。如果要保持原字符串的完整,可以使用strchr和sscanf的组合等。
- 函数第一次调用需设置两个参数。第一次分割的结果,返回串中第一个 ‘,’ 之前的字符串,也就是上面的程序第一次输出abc。
- 第二次调用该函数strtok(NULL,","),第一个参数设置为NULL。结果返回分割依据后面的字串,即第二次输出d。
int main()
{
char s[] = "zhangyi.123@1234";
char delim[] = ".@";
//找到第一个位置并打印
char *string = strtok(s, delim);
printf("%s\n", string);
//找到第二个位置并打印
char *string1 = strtok(NULL, delim);
printf("%s\n", string1);
//找到第三个位置并打印
char *string2 = strtok(NULL, delim);
printf("%s\n", string2);
return 0;
}
//简单版
int main()
{
char s[] = "zhangyi.123@1234";
char delim[] = ".@";
char *p;
for (p = strtok(s, delim); p != NULL; p = strtok(NULL, delim))
{
printf("%s\n", p);
}
return 0;
}
5. strstr(重点)
5.1 定义
描述
C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 ‘\0’。
声明
下面是 strstr() 函数的声明。
char *strstr(const char *haystack, const char *needle)
参数
- haystack – 要被检索的 C 字符串。
- needle – 在 haystack 字符串内要搜索的小字符串。
返回值
该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。
5.2 代码实现
/**
* 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。
* @param haystack 要被检索的 C 字符串
* @param needle 在 haystack 字符串内要搜索的小字符串
* @return 该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null
*/
char *my_strstr(const char *haystack, const char *needle)
{
//防止空指针
assert(haystack);
assert(needle);
//分别记录初始位置
const char *p1 = haystack;
const char *p2 = needle;
//定义开始查找的位置指针,第一次从haystack起始位置开始查找
const char *sp = haystack;
//当开始查找的位置不为‘\0’,循环查找
while (*sp)
{
//每次重新查找前将 开始查找位置指针 赋给p1,将指向子串的指针回归到子串起始位置
p1 = sp;
p2 = needle;
//如果当前匹配的元素相等且均不为‘\0’,则两个指针后移
while (*p1 && *p2 && *p1 == *p2)
{
p1++;
p2++;
}
//跳出循环有三种情况 *p1=‘\0’ *p2=‘\0’ *p1 != *p2
//情况1:*p2=‘\0’表示已经找到了待匹配的字符串,则返回开始查找的位置
if (*p2 == '\0')
{
return (char *) sp;
}
//情况2:*p1=‘\0’表示原串已经找完,但还没匹配完子串,所以返回NULL
else if (*p1 == '\0')
{
return NULL;
}
//情况3:如果出现不相等,记录查找开始位置的指针后移,进行下一次循环
sp++;
}
//结束后还未匹配到子串
return NULL;
}
5.3 实例
int main()
{
char s1[] = "abcdef";
char s2[] = "bcd";
char *string = my_strstr(s1, s2);
printf("子字符串是:%s", string);
return 0;
}
让我们编译并运行上面的程序,这将产生以下结果:
子字符串是: bcdef
6. strerror
6.1 定义
描述
C 库函数 char *strerror(int errnum) 从内部数组中搜索错误号 errnum,并返回一个指向错误消息字符串的指针。strerror 生成的错误字符串取决于开发平台和编译器。
声明
char *strerror(int errnum)
参数
- errnum – 错误号,通常是 errno。
返回值
该函数返回一个指向错误字符串的指针,该错误字符串描述了错误 errnum。
6.2 实例
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
//以只读形式打开文件file.txt
FILE * fp = fopen("file.txt","r");
//如果文件不存在,打印错误信息
if( fp == NULL )
{
printf("Error: %s\n", strerror(errno));
}
return 0 ;
}
让我们编译并运行上面的程序,这将产生以下结果,因为我们尝试打开一个不存在的文件:
Error: No such file or directory
7. perror
7.1 定义
描述
把一个描述性错误消息输出到标准错误 stderr。首先输出字符串 str,后跟一个冒号,然后是一个空格。(与sterror类似,但比其简单)
声明
void perror(const char *str)
参数
- str – 这是 C 字符串,包含了一个自定义消息,将显示在原本的错误消息之前。
返回值
该函数不返回任何值。
7.2 实例
#include <stdio.h>
#include <string.h>
int main ()
{
//以只读形式打开文件file.txt
FILE * fp = fopen("file.txt","r");
//如果文件不存在,打印错误信息
if( fp == NULL )
{
perror("自定义错误信息:")
}
return 0 ;
}
让我们编译并运行上面的程序,这将产生以下结果,因为我们尝试打开一个不存在的文件:
自定义错误信息: No such file or directory
8.字符函数
函数名 | 介绍 |
---|---|
int isalnum(int c) | 检查字符是否为数字或字母;(09,az,A~Z) |
int isalpha(int c) | 检查字符是否为字母;(a~z, A~Z) |
int iscntrl(int c) | 检查字符是否为控制字符;(八进制000~037以及177的字符) |
int isdigit(int c) | 检查字符是否为十进制数字;(0~9) |
int isgraph(int c) | 检查字符是否为图形表示,依赖于使用语言的环境;09,az,A~Z,以及标点符号) |
int islower(int c) | 检查字符是否为小写的字母;(a~z) |
int isprint(int c) | 检查字符是否为可打印的;(数字、字母、标点符号、空白字符) |
int ispunct(int c) | 检查字符是否为标点符号;(! ” # $ % & ’ ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~等) |
int isspace(int c) | 检查字符是否为空白字符;(TAB、换行、垂直TAB、换页、回车、空格) |
int isupper(int c) | 检查字符是否为大写字母;(A~Z) |
int isxdigit(int c) | 检查字符是否为十六进制数字;(0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f) |
int tolower(int c) | 转化字符为小写字母; |
int toupper(int c) | 转化字符为大写字母; |