轻松高效拿捏C语言20常用的字符串函数

程序员Feri一名12年+的程序员,做过开发带过团队创过业,擅长Java、鸿蒙、嵌入式、人工智能等开发,专注于程序员成长的那点儿事,希望在成长的路上有你相伴!君志所向,一往无前!


1、字符串相关函数

1.1 字符串的表示方式

C 语言没有单独的字符串类型,字符串被当作字符数组,即 char 类型的数组。表示方式如下:

方式1:

char str[] = "hello";

方式2:

char *str = "hello";

1.2 两种方式的区别

字符指针和字符数组,这两种声明字符串变量的写法基本是等价的,但是也有区别。

区别1:指针指向的字符串,在 C 语言内部被当作常量,不能修改字符串本身。

char* str = "hello!";
str[0] = 'z'; // 报错

如果使用数组声明字符串变量,就没有这个问题,可以修改数组的任意成员。

char str[] = "hello";
str[0] = 'z'; // 不报错

为什么字符串声明为指针时不能修改,声明为数组时就可以修改?

因为系统会将字符串的字面量保存在内存的常量区,这个区域是不允许用户修改的。声明为指针时,指针变量存储的值是一个指向常量区的内存地址,因此用户不能通过这个地址去修改常量区。

但是,声明为数组时,编译器会给数组单独分配一段内存,字符串字面量会被编译器解释成字符数组,逐个字符写入这段新分配的内存之中,而这段新内存是允许修改的。

测试代码:

int main() {

    char str1[] = "hello"; //新开辟的空间,保存数组中的数据
    char str2[] = "hello"; //新开辟的空间,保存数组中的数据
    printf("%p\n",str1); //000000f4a93ff81a
    printf("%p\n",str2); //000000f4a93ff814

    char * str3 = "hello"; 
    char * str4 = "hello"; //与前一个str3的数据是共享的,存在于常量区
    printf("%p\n",str3); //00007ff6842ca004
    printf("%p\n",str4); //00007ff6842ca004
    
    return 0;
}

区别2:指针变量可以指向其它字符串。

char* s = "hello";
s = "world";

但是,字符数组变量不能指向另一个字符串。

char s[] = "hello";
s = "world"; // 报错

字符数组的数组名,总是指向初始化时的字符串地址,不能修改。所以,声明字符数组后,不能直接用字符串赋值。

char s[10];
s = "abc"; // 错误

为什么数组变量不能赋值为另一个数组?

因为数组变量所在的地址无法改变,或者说,编译器一旦为数组变量分配地址后,这个地址就绑定这个数组变量了,这种绑定关系是不变的,即不能用赋值运算符为它重新赋值。

想要重新赋值,必须使用 C 语言原生提供的 strcpy() 函数,通过字符串拷贝完成赋值。

这样做以后,数组变量的地址还是不变的,即 strcpy() 只是在原地址写入新的字符串,而不是让数组变量指向新的地址。

char s[10];
strcpy(s, "abc");

1.2 字符串常用函数

这里的字符串处理函数,都属于库函数

库函数并非C语言本身的组成部分,而是C语言编译系统为方便用户使用而提供的公共函数。

不同的编译系统提供的函数数量和函数名、函数功能都不尽相同,使用时要小心,必要时查一下库函数手册

在使用字符串处理函数时,应当在程序文件的开头用#include <string.h>把 string.h 文件包含到本文件中。

strlen()

作用:返回字符串的字节长度,不包括末尾的空字符 '\0' 。

函数原型:

// string.h
//参数是字符串变量,返回的是 size_t 类型的无符号整数,一般当做int类型处理。
size_t strlen(const char* s);

举例:

#include <stdio.h>
#include <string.h>    //需要加载此头文件

int main() {
    char str[10] = "China";
    printf("%d\n", strlen(str));     //5

    printf("%d\n", strlen("China")); //5
    
    //区别于sizeof(),是两个不同的概念
    printf("%d\n", sizeof(str));        //10
}
strcpy()

strcpy(字符数组1, 字符数组2) :字符串的复制,不能使用赋值运算符,直接将字符数组2的字符串复制到字符数组1中。

函数原型:

// string.h
strcpy(char dest[], const char source[])

使用此函数前,如何复制字符串呢?

一方面,下面两种字符串的复制写法,都是错的。因为数组的变量名是一个固定的地址,不能修改,使其指向另一个地址。

char str1[10];
char str2[10];
str1 = "abc"; // 报错
str2 = str1;  // 报错

另一方面,如果是字符指针,赋值运算符( = )只是将一个指针的地址复制给另一个指针,而不是复制字符串。

char* str1;
char* str2;

str1 = "abc";
str2 = str1;

此时,可以使用 strcpy(字符数组1,字符数组2) 函数,用于将一个字符串的内容复制到另一个字符串(前提:字符数组1的长度不小于字符数组2的长度,否则会溢出)。

举例:

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

int main() {
    char str1[10], str2[] = "China";
    strcpy(str1, str2);
    
    printf("%s\n",str1);

    //或
//    strcpy(str1, "China"); //参数2,也可以是一个字符串常量
//    printf("%s\n",str1);
    
    //进一步
    str1[0] = 'A';
    printf("%s\n",str1); //Ahina
    printf("%s\n",str2); //China
}

思考:如下程序的输出结果

int main() {

    char str1[10] = "abcde1234", str2[] = "China";
    strcpy(str1, str2);

    printf("%s\n",str1); //

    for(int i = 0;i < 10;i++){
        printf("%c",str1[i]); //
    }
    printf("\n");

    return 0;
}
China
China 2345

复制时将字符串2和其后的′\0′一起复制到字符数组1中,取代字符数组1中前面的字符,未被取代的字符保持原有内容。

strncpy()

作用:将字符串2中前面n个字符复制到字符数组1中去。

strncpy(str1, str2, n);

将str2中最前面n个字符复制到str1中,取代str1中原有的最前面n个字符。但复制的字符个数n不应多于str1中原有的字符(不包括′\0′)。

int main() {

    char s1[40] = "1234567890";
    char s2[12] = "helloworld";
    strncpy(s1, s2, 5);
//    s1[5] = '\0';  //测试这行代码添加的必要性
    printf("%s\n", s1); // 

    return 0;
}
strcat()

**strcat(字符数组1, 字符数组2)**:把两个字符数组中的字符串连接起来,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值——字符数组1的地址。

函数原型:

char* strcat(char* s1, const char* s2);

说明:

1、字符数组1必须足够大,以便容纳连接后的新字符串。

2、连接前两个字符串的后面都有′\0′,连接时将字符串1后面的′\0′取消,只在新串最后保留′\0′。

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

int main() {
    char str1[30] = {"People′s Republic of "};
    char str2[] = {"China"};
    printf("%s\n", strcat(str1, str2)); //People′s Republic of China
    printf("%s\n", str1);  //People′s Republic of China

}
strncat()

作用:将字符串2中前面n个字符连接到字符数组1中去。

strncat(str1, str2, n);

strncat() 总是会在拼接结果的结尾,自动添加空字符′\0′ ,所以第三个参数的最大值,应该是 str1 的变量长度减去 str1 的字符串长度,再减去 1 。

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

int main() {

    char s1[10] = "Hello";
    char s2[8] = "World";
    strncat(s1, s2, 3);
    printf("%s\n", s1);  //HelloWor
    return 0;
}
strcmp()

函数原型:

int strcmp(const char* s1, const char* s2);

**strcmp(字符串1, 字符串2)**:比较字符串1和字符串2。

字符串比较的规则是:将两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到′\0′为止。

(1) 如全部字符相同,则认为两个字符串相等。返回值为0

(2) 若出现不相同的字符,如果返回值为正数,则字符串1大;反之,返回值为负数,则字符串2大。

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

int main() {
    char *str1 = "abxy";
    char *str2 = "abmn";
    printf("%d\n",strcmp(str1, str2));  // 1

    int compare1 = strcmp("China", "Korea");
    printf("%d\n",compare1);  // -1

    return 0;
}
strlwr()/strupr()

**strlwr(字符串)**:将字符串中大写字母换成小写字母。

**strupr(字符串)**:将字符串中小写字母换成大写字母。

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

int main() {

    char str[] = "HelloWorld";
    strlwr(str);
    puts(str); //helloworld

    strupr(str);
    puts(str); //HELLOWORLD
}

1.3 基本数据类型和字符串的转换

在程序开发中,我们经常需要将基本数据类型转成字符串类型(即 char数组 )。或者将字符串类型转成基本数据类型。

基本数据类型 -> 字符串

sprintf()函数可以将其他数据类型转换成字符串类型。此函数声明在stdio.h头文件中。

sprintf()和平时我们常用的printf()函数的功能相似,只是sprintf()函数输出到字符串中,而printf()函数输出到屏幕上。

#include <stdio.h>

int main() {
    char str1[20]; //字符数组,即字符串
    char str2[20];
    char str3[20];
    int a = 111, b = 222;
    char c = 'a';
    double d = 333.444;


    sprintf(str1, "%d %d", a, b);
    sprintf(str2, "%d%c", a, c);
    sprintf(str3, "%.5f", d);
    printf("str1=%s\n", str1); //111 222
    printf("str2=%s\n", str2); //111a
    printf("str3=%s\n", str3); //333.44400
    
    return 0;
}
字符串 -> 基本数据类型

调用头文件 <stdlib.h> 的函数atoi()atof() 即可。

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

int main() {
    char str1[10] = "123456";
    char str2[4] = "111";
    char str3[10] = "12.67423";
    char str4[2] = "a";

    int i = atoi(str1);
    int j = atof(str1);
    short s = atoi(str2);
    double d = atof(str3);
    char c = str4[0];
    printf("i=%d,j=%d,s=%d,d=%lf,c=%c", i, j, s, d, c);

    return 0;
}

好啦,就到这里吧,再坚持坚持C语言快速入门就更新完啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值