Skip to content

字符串

  • C语⾔中没有字符串这种数据类型,可以通过char的数组(字符数组)来替代;
  • 字符串一定是一个char的数组,但char的数组未必是字符串;
  • `‘\0’`,但如果char数组没有以数字0结尾,那么就不是一个字符串,只是普通字符数组,所以
c
#include <stdio.h>
#include <stdlib.h>

int main() {
    char c1[] = {'c', ' ', 'p', 'r', 'o', 'g'};//普通字符数组
    printf("c1 = %s\n", c1);                   //乱码,因为没有’\0’结束符

    //以‘\0’(‘\0’就是数字0)结尾的字符数组是字符串
    char c2[] = {'c', ' ', 'p', 'r', 'o', 'g', '\0'};
    printf("c2 = %s\n", c2);

    //字符串处理以‘\0’(数字0)作为结束符,后⾯的'h', 'l', 'l', 'e', 'o'不会输出
    char c3[] = {'c', ' ', 'p', 'r', 'o', 'g', '\0', 'h', 'l', 'l', 'e', 'o', '\0'};
    printf("c3 = %s\n", c3);

    return 0;
}

程序输出:

shell
c1 = c prog烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫
c2 = c prog
c3 = c prog

字符串的初始化

c
#include <stdio.h> 
#include <stdlib.h>

// C语⾔没有字符串类型,通过字符数组模拟
// C语⾔字符串,以字符‘\0’, 数字0

int main() {
    //不指定长度, 没有0结束符,有多少个元素就有多长
    char buf[] = {'a', 'b', 'c'};
    printf("buf = %s\n", buf);//乱码

    //指定长度,后⾯没有赋值的元素,⾃动补0
    char buf1[100] = {'a', 'b', 'c'};
    char buf2[1000] = {"hello"};
    printf("buf1 = %s\n", buf1);

    //所有元素赋值为0
    char buf3[100] = {0};

    //char buf4[2] = { '1', '2', '3' };//数组越界

    char buf5[50] = {'1', 'a', 'b', '0', '7'};
    printf("buf5 = %s\n", buf5);

    char buf6[50] = {'1', 'a', 'b', 0, '7'};
    printf("buf6 = %s\n", buf6);

    char buf7[50] = {'1', 'a', 'b', '\0', '7'};
    printf("buf7 = %s\n", buf7);

    //使用字符串初始化,编译器⾃动在后⾯补0,常用
    char buf8[] = "agjdslgjlsdjg";

    //'\0'后⾯最好不要连着数字,有可能⼏个数字连起来刚好是一个转义字符
    // '\ddd'⼋进制字义字符,'\xdd'⼗六进制转移字符
    // \012相当于\n
    char str[] = "\012abc";
    printf("str == %s\n", str);

    return 0;
}

程序输出:

shell
buf = abc烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫?
buf1 = abc
buf5 = 1ab07
buf6 = 1ab
buf7 = 1ab
str == 
abc

字符串基本操作

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//字符串基本操作
//字符串是以0或者'\0'结尾的字符数组,(数字0和字符'\0'等价)
void test() {
    //字符数组只能初始化5个字符,当输出的时候,从开始位置直到找到0结束
    char str1[] = {'h', 'e', 'l', 'l', 'o'};
    printf("%s\n", str1);

    //字符数组部分初始化,剩余填0
    char str2[100] = {'h', 'e', 'l', 'l', 'o'};
    printf("%s\n", str2);

    //如果以字符串初始化,那么编译器默认会在字符串尾部添加'\0'
    char str3[] = "hello";
    printf("%s\n", str3);
    printf("sizeof str:%d\n", sizeof(str3));
    printf("strlen str:%d\n", strlen(str3));

    //sizeof计算数组⼤⼩,数组包含'\0'字符
    //strlen计算字符串的长度,到'\0'结束
    //那么如果我这么写,结果是多少呢?
    char str4[100] = "hello";
    printf("sizeof str:%d\n", sizeof(str4));
    printf("strlen str:%d\n", strlen(str4));

    //请问下⾯输⼊结果是多少?sizeof结果是多少?strlen结果是多少?
    char str5[] = "hello\0world";
    printf("%s\n", str5);
    printf("sizeof str5:%d\n", sizeof(str5));
    printf("strlen str5:%d\n", strlen(str5));

    //再请问下⾯输⼊结果是多少?sizeof结果是多少?strlen结果是多少?
    char str6[] = "hello\012world";
    printf("%s\n", str6);
    printf("sizeof str6:%d\n", sizeof(str6));
    printf("strlen str6:%d\n", strlen(str6));
}

int main(void) {
    test();

    return 0;
}

程序输出:

shell
hello烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫
hello
hello
sizeof str:6
strlen str:5
sizeof str:100
strlen str:5
hello
sizeof str5:12
strlen str5:5
hello
world
sizeof str6:12
strlen str6:11

八进制和十六进制转义字符:

在C中有两种特殊的字符,⼋进制转义字符和⼗六进制转义字符,⼋进制字符的一般形式是'\ddd',d是0-7的数字。⼗六进制字符的一般形式是'\xhh',h是0-9或A-F内的一个。⼋进制字符和⼗六进制字符表⽰的是字符的ASCII码对应的数值。比如 :

  • '\063'表⽰的是字符'3',因为'3'的ASCII码是30(⼗六进制),48(⼗进制),63(⼋进制)。
  • '\x41'表⽰的是字符'A',因为'A'的ASCII码是41(⼗六进制),65(⼗进制),101(⼋进制)。

字符串的输入输出

由于字符串采用了'\0'标志,字符串的输⼊输出将变得简单⽅便。

c
#include <stdio.h> 
#include <stdlib.h>

int main() {
    char str[100];

    printf("input string1 : \n"); 
    scanf("%s", str);   //scanf(“%s”,str)默认以空格分隔 
    printf("output:%s\n", str);

    return 0;
}

程序输出:

shell
input string1 : 
hello c↙️
output:hello

gets()

c
#include <stdio.h> 
char *gets(char *s);

功能:从标准输⼊读⼊字符,并保存到s指定的内存空间,直到出现换行符或读到文件结尾为⽌。

参数

  • s:字符串⾸地址

返回值

  • 成功:读⼊的字符串
  • 失败:NULL
gets(str)scanf(“%s”,str)的区别
  • gets(str)允许输⼊的字符串含有空格
  • scanf(“%s”,str)不允许含有空格
⚠️注意

由于scanf()gets()⽆法知道字符串s⼤⼩,必须遇到换行符或读到文件结尾为⽌才接收输⼊,因此容易导致字符数组越界(缓冲区溢出)的情况。

c
char str[100]; 
printf("请输⼊str: "); 
gets(str); 
printf("str = %s\n", str);

fgets()

c
#include <stdio.h> 
char *fgets(char *s, int size, FILE *stream);

功能:从stream指定的文件内读⼊字符,保存到s所指定的内存空间,直到出现换行字符、读到文件结尾或是已读了size - 1个字符为⽌,最后会⾃动加上字符 '\0' 作为字符串结束。

参数

  • s:字符串
  • size:指定最⼤读取字符串的长度(size - 1
  • stream:文件指针,

返回值

  • 成功:成功读取的字符串
  • 读到文件尾或出错:NULL

fgets()在读取一个用户通过键盘输⼊的字符串的时候,同时把用户输⼊的回车也做为字符串的一部分。通过scanf和gets输⼊一个字符串的时候,不包含结尾的“\n”,\n fgets()函数是安全的,不存在缓冲区溢出的问题。

c
char str[100]; 
printf("请输⼊str: "); 
fgets(str, sizeof(str), stdin); 
printf("str = \"%s\"\n", str);

puts()

c
#include <stdio.h> 
int puts(const char *s);

功能:标准设备输出s字符串, '\n'

参数

  • s:字符串首地址

返回值

  • 成功:非负数
  • 失败:-1
c
#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("hello world");
    puts("hello world");

    return 0;
}

程序输出:

shell
hello worldhello world

fputs()

c
#include <stdio.h> 
int fputs(const char * str, FILE * stream);

功能:将str所指定的字符串写⼊到stream指定的文件中, 字符串结束符 '\0' 不写⼊文件。

参数

  • str:字符串
  • stream:文件指针,stdout

返回值

  • 成功:0
  • 失败:-1

fputs()是puts()的文件操作版本,但fputs()⾃动输出一个'\n'

c
printf("hello world"); 
puts("hello world"); 
fputs("hello world", stdout);

sprintf

c
#include <stdio.h>
int sprintf(char *str, const char *format, …);

功能:根据参数format字符串来转换并格式化数据,然后将结果输出到str指定的空间中,直到出现字符串结束符 ‘\0’ 为⽌。

参数

  • str :字符串⾸地址
  • format :字符串格式,用法和printf()一样

返回值

  • 成功:实际格式化的字符个数
  • 失败: -1
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void test() {
    //1. 格式化字符串
    char buf[1024] = {0};
    sprintf(buf, "你好,%s,欢迎加⼊我们!", "John");
    printf("buf:%s\n", buf);
    memset(buf, 0, 1024);
    sprintf(buf, "我今年%d岁了!", 20);
    printf("buf:%s\n", buf);

    //2. 拼接字符串 memset(buf, 0, 1024);
    char str1[] = "hello";
    char str2[] = "world";
    int len = sprintf(buf, "%s %s", str1, str2);
    printf("buf:%s len:%d\n", buf, len);

    //3. 数字转字符串 memset(buf, 0, 1024);
    int num = 100;
    sprintf(buf, "%d", num);
    printf("buf:%s\n", buf);

    //设置宽度 右对齐
    memset(buf, 0, 1024);
    sprintf(buf, "%8d", num);
    printf("buf:%s\n", buf);

    //设置宽度 左对齐
    memset(buf, 0, 1024);
    sprintf(buf, "%-8d", num);
    printf("buf:%s\n", buf);

    //转成16进制字符串 ⼩写
    memset(buf, 0, 1024);
    sprintf(buf, "0x%x", num);
    printf("buf:%s\n", buf);

    //转成8进制字符串
    memset(buf, 0, 1024);
    sprintf(buf, "0%o", num);
    printf("buf:%s\n", buf);
}

int main(void) {
    test();

    return 0;
}

程序输出:

shell
buf:你好,John,欢迎加⼊我们!
buf:我今年20岁了!
buf:hello world len:11
buf:100
buf:     100
buf:100     
buf:0x64
buf:0144

sscanf

c
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);

功能:从str指定的字符串读取数据,并根据参数format字符串来转换并格式化数据。

参数

  • str :字符串⾸地址
  • format :字符串格式,用法和scanf()一样

返回值

  • 成功:参数数目
  • 失败: -1
格式作用
%*s%*d跳过数据
%[width]s读指定宽度的数据
%[a-z]匹配a到z中任意字符(尽可能多的匹配)
%[aBc]匹配a、B、c中一员,贪婪性
%[^a]匹配非a的任意字符,贪婪性
%[^a-z]表⽰读取除a-z以外的所有字符
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//1. 跳过数据
void test01() {
    char buf[1024] = {0};
    //跳过前⾯的数字
    //匹配第一个字符是否是数字,如果是,则跳过
    //如果不是则停⽌匹配
    sscanf("123456aaaa", "%*d%s", buf);
    printf("buf:%s\n", buf);
}

//2. 读取指定宽度数据
void test02() {
    char buf[1024] = {0};
    //跳过前⾯的数字
    sscanf("123456aaaa", "%7s", buf);
    printf("buf:%s\n", buf);
}

//3. 匹配a-z中任意字符
void test03() {
    char buf[1024] = {0};
    //跳过前⾯的数字
    //先匹配第一个字符,判断字符是否是a-z中的字符,如果是匹配
    //如果不是停⽌匹配
    sscanf("abcdefg123456", "%[a-z]", buf);
    printf("buf:%s\n", buf);
}

//4. 匹配aBc中的任何一个
void test04() {
    char buf[1024] = {0};
    //跳过前⾯的数字
    //先匹配第一个字符是否是aBc中的一个,如果是,则匹配,如果不是则停⽌匹配
    sscanf("abcdefg123456", "%[aBc]", buf);
    printf("buf:%s\n", buf);
}

//5. 匹配非a的任意字符
void test05() {
    char buf[1024] = {0};
    //跳过前⾯的数字
    //先匹配第一个字符是否是aBc中的一个,如果是,则匹配,如果不是则停⽌匹配
    sscanf("bcdefag123456", "%[^a]", buf);
    printf("buf:%s\n", buf);
}

//6. 匹配非a-z中的任意字符
void test06() {
    char buf[1024] = {0};
    //跳过前⾯的数字
    //先匹配第一个字符是否是aBc中的一个,如果是,则匹配,如果不是则停⽌匹配
    sscanf("123456ABCDbcdefag", "%[^a-z]", buf);
    printf("buf:%s\n", buf);
}

int main(void) {
    printf("test01 print:\n");
    test01();
    printf("\n\ntest02 print:\n");
    test02();
    printf("\n\ntest03 print:\n");
    test03();
    printf("\n\ntest04 print:\n");
    test04();
    printf("\n\ntest05 print:\n");
    test05();
    printf("\n\ntest06 print:\n");
    test06();

    return 0;
}

程序输出:

shell
test01 print:
buf:aaaa


test02 print:
buf:123456a


test03 print:
buf:abcdefg


test04 print:
buf:a


test05 print:
buf:bcdef


test06 print:
buf:123456ABCD

统计字符串长度

strlen()

c
#include <string.h> 
size_t strlen(const char *s);

功能:计算指定指定字符串s的长度,

参数

  • s:字符串首地址

返回值:字符串s的长度,size_tunsigned int类型

c
char str[] = "abc\0defg";
int n = strlen(str); 
printf("n = %d\n", n);

强化训练:字符串拼接

c
#include <stdio.h>
#include <stdlib.h>

int main() {
    char str1[] = "abcdef";
    char str2[] = "123456";
    char dst[100];

    int i = 0;
    while (str1[i] != 0) {
        dst[i] = str1[i];
        i++;
    }

    int j = 0;
    while (str2[j] != 0) {
        dst[i + j] = str2[j];
        j++;
    }
    dst[i + j] = 0;//字符串结束符

    printf("dst = %s\n", dst);

    return 0;
}

程序输出:

shell
dst = abcdef123456

项目开发常用字符串应用模型

strstr中的while和do-while模型

利用strstr标准库函数找出一个字符串中substr出现的个数。

while模型

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char *p = "11abcd111122abcd333abcd3322abcd3333322qqq";
    int n = 0;

    while ((p = strstr(p, "abcd")) != NULL) {
        //能进来,肯定有匹配的⼦串
        //重新设置起点位置
        p = p + strlen("abcd");
        n++;
        //如果到结束符
        if (*p == 0) {
            break;
        }
    }

    printf("n = %d\n", n);

    return 0;
}

程序输出:

shell
n = 4

do-while模型

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char *p = "11abcd111122abcd333abcd3322abcd3333322qqq";
    int n = 0;

    do {
        p = strstr(p, "abcd");
        if (p != NULL) {
            n++;//累计个数

            //重新设置查找的起点
            p = p + strlen("abcd");

        } else//如果没有匹配的字符串,跳出循环
        {
            break;
        }
    } while (*p != 0);//如果没有到结尾

    printf("n = %d\n", n);

    return 0;
}

程序输出:

shell
n = 4

两头堵模型

求非空字符串元素的个数

c
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int fun(char *p, int *n) {
    if (p == NULL || n == NULL) { return -1; }

    int begin = 0;
    int end = strlen(p) - 1;

    //从左边开始
    //如果当前字符为空,而且没有结束
    while (p[begin] == ' ' && p[begin] != 0) {
        begin++;//位置从右移动一位
    }

    //从右往左移动
    while (p[end] == ' ' && end > 0) {
        end--;//往左移动
    }

    if (end == 0) {
        return -2;
    }

    //非空元素个数
    *n = end - begin + 1;
    return 0;
}

int main(void) {
    char *p = "           abcddsgadsgefg              ";
    int ret = 0;
    int n = 0;

    ret = fun(p, &n);
    if (ret != 0) {
        return ret;
    }

    printf("非空字符串元素个数:%d\n", n);

    return 0;
}

程序输出:

shell
非空字符串元素个数:14

字符串反转模型(逆置)

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int inverse(char *p) {
    if (p == NULL) { return -1; }
    char *str = p;
    int begin = 0;
    int end = strlen(str) - 1;
    char tmp;
    while (begin < end) {
        //交换元素
        tmp = str[begin];
        str[begin] = str[end];
        str[end] = tmp;

        begin++;//往右移动位置
        end--;  //往左移动位置
    }

    return 0;
}

int main(void) {
    //char *str = "abcdefg"; //文件常量区,内容不允许修改
    char str[] = "abcdef";

    int ret = inverse(str);
    if (ret != 0) {
        return ret;
    }

    printf("str ========== %s\n", str);

    return 0;
}

程序输出:

shell
str ========== fedcba

字符串处理函数

strcpy()

c
#include <string.h> 
char *strcpy(char *dest, const char *src);

功能:把src所指向的字符串复制到dest所指向的空间中,

参数

  • dest:目的字符串⾸地址
  • src:源字符⾸地址

返回值

  • 成功:返回dest字符串的⾸地址
  • 失败: NULL

注意:如果参数dest所指的内存空间不够⼤,可能会造成缓冲溢出的错误情况。

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char dest[20] = "123456789";
    char src[] = "hello world";
    strcpy(dest, src);
    printf("%s\n", dest);

    return 0;
}

程序输出:

shell
hello world

strncpy()

c
#include <string.h> 
char *strncpy(char *dest, const char *src, size_t n);

功能:把src指向字符串的前n个字符复制到dest所指向的空间中,

参数

  • dest:目的字符串⾸地址
  • src:源字符⾸地址
  • n:指定需要拷贝字符串个数

返回值

  • 成功:返回dest字符串的⾸地址
  • 失败: NULL
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char dest[20];
    char src[] = "hello world";

    strncpy(dest, src, 5);
    printf("%s\n", dest);

    dest[5] = '\0';
    printf("%s\n", dest);

    return 0;
}

程序输出:

shell
hello烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫
hello

strcat()

c
#include <string.h> 
char *strcat(char *dest, const char *src);

功能:将src字符串连接到dest的尾部,‘\0’也会追加过去

参数

  • dest:目的字符串⾸地址
  • src:源字符⾸地址

返回值

  • 成功:返回dest字符串的⾸地址
  • 失败: NULL
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char str[20] = "123";
    char *src = "hello world";

    printf("%s\n", strcat(str, src));

    return 0;
}

程序输出:

shell
123hello world

strncat()

c
#include <string.h> 
char *strncat(char *dest, const char *src, size_t n);

功能:将src字符串前n个字符连接到dest的尾部,‘\0’也会追加过去

参数

  • dest :目的字符串⾸地址
  • src :源字符⾸地址
  • n :指定需要追加字符串个数

返回值

  • 成功:返回dest字符串的⾸地址
  • 失败: NULL
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char str[20] = "123";
    char *src = "hello world";

    printf("%s\n", strncat(str, src, 5));

    return 0;
}

程序输出:

shell
123hello

strcmp()

c
#include <string.h> 
int strcmp(const char *s1, const char *s2);

功能:比较 s1 和 s2 的⼤⼩,

参数

  • s1 :字符串1⾸地址
  • s2 :字符串2⾸地址

返回值

  • 相等: 0
  • ⼤于: >0 在不同操作系统strcmp结果会不同 返回ASCII差值
  • ⼩于: <0
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char *str1 = "hello world";
    char *str2 = "hello mike";

    if (strcmp(str1, str2) == 0) {
        printf("str1==str2\n");

    } else if (strcmp(str1, str2) > 0) {
        printf("str1>str2\n");
    } else {
        printf("str1<str2\n");
    }

    return 0;
}

程序输出:

shell
str1>str2

strncmp()

c
#include <string.h> 
int strncmp(const char *s1, const char *s2, size_t n);

功能:比较 s1 和 s2 前n个字符的⼤⼩,

参数

  • s1 :字符串1⾸地址
  • s2 :字符串2⾸地址
  • n :指定比较字符串的数量

返回值

  • 相等: 0
  • ⼤于: >0
  • ⼩于: <0
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char *str1 = "hello world";
    char *str2 = "hello mike";

    if (strncmp(str1, str2, 5) == 0) {
        printf("str1==str2\n");
    } else if (strcmp(str1, "hello world") > 0) {
        printf("str1>str2\n");
    } else {
        printf("str1<str2\n");
    }

    return 0;
}

程序输出:

shell
str1==str2

sprintf()

c
#include <stdio.h> 
int sprintf(char *str, const char *format, ...);

功能:根据参数format字符串来转换并格式化数据,然后将结果输出到str指定的空间中,直到出现字符串结束符 '\0' 为⽌。

参数

  • str :字符串⾸地址
  • format :字符串格式,用法和printf()一样

返回值

  • 成功:实际格式化的字符个数
  • 失败: -1
c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char dst[100] = {0};
    int a = 10;
    char src[] = "hello world";
    printf("a = %d, src = %s", a, src);
    printf("\n");
    int len = sprintf(dst, "a = %d, src = %s", a, src);
    printf("dst = \" %s\"\n", dst);
    printf("len = %d\n", len);

    return 0;
}

程序输出:

shell
a = 10, src = hello world
dst = " a = 10, src = hello world"
len = 25

sscanf()

c
#include <stdio.h> 
int sscanf(const char *str, const char *format, ...);

功能:从str指定的字符串读取数据,并根据参数format字符串来转换并格式化数据。

参数

  • str :指定的字符串⾸地址
  • format :字符串格式,用法和scanf()一样

返回值

  • 成功:参数数目,成功转换的值的个数
  • 失败: -1
c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char src[] = "a=10, b=20";
    int a;
    int b;
    sscanf(src, "a=%d, b=%d", &a, &b);
    printf("a:%d, b:%d\n", a, b);

    return 0;
}

程序输出:

shell
a:10, b:20

strchr()

c
#include <string.h> 
char *strchr(const char *s, int c);

功能:在字符串s中查找字母c出现的位置

参数

  • s :字符串⾸地址
  • c :匹配字母(字符)

返回值

  • 成功:返回第一次出现的c地址
  • 失败: NULL
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char src[] = "ddda123abcd";
    char *p = strchr(src, 'a');
    printf("p = %s\n", p);

    return 0;
}

程序输出:

shell
p = a123abcd

strstr()

c
#include <string.h> 
char *strstr(const char *haystack, const char *needle);

功能:在字符串haystack中查找字符串needle出现的位置

参数

  • haystack :源字符串⾸地址
  • needle :匹配字符串⾸地址

返回值

  • 成功:返回第一次出现的needle地址
  • 失败: NULL
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char src[] = "ddddabcd123abcd333abcd";
    char *p = strstr(src, "abcd");
    printf("p = %s\n", p);

    return 0;
}

程序输出:

shell
p = abcd123abcd333abcd

strtok()

c
#include <string.h> 
char *strtok(char *str, const char *delim);

功能:来将字符串分割成一个个⽚段。当strtok()在参数str的字符串中发现参数delim中包含的分割字符时, 则会将该字符改为\0 字符,当连续出现多个时只替换第一个为\0

参数

  • str :指向欲分割的字符串
  • delim :为分割字符串中包含的所有字符

返回值

  • 成功:分割后字符串⾸地址
  • 失败: NULL

在第一次调用时strtok()必需给予参数str字符串,往后的调用则将参数str设置成NULL,每次调用成功则返回指向被分割出⽚段的指针。

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char a[100] = "adc*fvcv.ebcy*hghbdfg$casdert";
    char *s = strtok(a, ".*$");//将"*"分割的⼦串取出
    while (s != NULL) {
        printf("%s\n", s);
        s = strtok(NULL, "*");
    }

    return 0;
}

程序输出:

shell
adc
fvcv.ebcy
hghbdfg$casdert

atoi()

c
#include <stdlib.h>
int atoi(const char *nptr);

功能:atoi()会扫描nptr字符串,跳过前⾯的空格字符,直到遇到数字或正负号才开始做转换,而遇到非数字或字符串结束符('\0')才结束转换,并将结果返回返回值。

参数

  • nptr :待转换的字符串

返回值:成功转换后整数

类似的函数有

  • atof() :把一个⼩数形式的字符串转化为一个浮点数。
  • atol() :将一个字符串转化为long类型
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char str1[] = "                     -10";
    int num1 = atoi(str1);
    printf("num1 = %d\n", num1);

    char str2[] = "0.123";
    double num2 = atof(str2);
    printf("num2 = %lf\n", num2);

    char str3[] = "123L";
    long num3 = atol(str3);
    printf("num3 = %ld\n", num3);

    return 0;
}

程序输出:

shell
num1 = -10
num2 = 0.123000
num3 = 123

字符串拷贝功能实现

c
//拷贝⽅法1
void copy_string01(char* dest, char* source) {
    for (int i = 0; source[i] != '\0'; i++) {
        dest[i] = source[i]; 
    }
}

//拷贝⽅法2
void copy_string02(char* dest, char* source) { 
    while (*source != '\0' /* *source != 0 */) {
        *dest = *source;
        source++;
        dest++;
    }
}

//拷贝⽅法3
void copy_string03(char* dest, char* source) {
    //判断*dest是否为0,0则退出循环
    while (*dest++ = *source++) {} 
}

字符串反转模型

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void reverse_string(char *str) {
    if (str == NULL) { return; }
    int begin = 0;
    int end = strlen(str) - 1;
    while (begin < end) {
        //交换两个字符元素
        char temp = str[begin];
        str[begin] = str[end];
        str[end] = temp;

        begin++;
        end--;
    }
}

void test() {
    char str[] = "abcdefghijklmn";
    printf("str:%s\n", str);
    reverse_string(str);
    printf("str:%s\n", str);
}

int main(void) {
    test();

    return 0;
}

程序输出:

shell
str:abcdefghijklmn
str:nmlkjihgfedcba