C语言零碎知识点之字符串

Posted 二木成林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言零碎知识点之字符串相关的知识,希望对你有一定的参考价值。

字符串的表示

C语言中并没有字符串这个类型,表示字符串时,需要使用字符数组,或字符指针。即 char 型数组,或char *指针。

如果使用字符数组表示:

// 可以不指定字符数组的长度,但如果指定字符数组长度那么应该比实际字符串中的字符个数大
char str[20] = "hello world";

// 注意,不能使用下面的方式赋值
char str[20];
str = "hello world";

如果用字符指针表示:

char* str = "hello world";

// 注意,支持先声明再赋值的方式
char* str;
str = "hello world";

从键盘输入字符串

通常我们可能会需要用户输入字符串,可以通过scanf函数或者gets函数来完成。

可以直接输入一个字符串并存储,程序会自动在结束时加字符串结束符'\\0'

无论是字符数组还是字符组指针,都可以通过scanf函数或者gets函数来输入:

// 1.字符数组
// 1.1 通过 scanf 函数输入,但注意不能输入带有空格的字符串
char str1[20];
scanf("%s", str1);
// 1.2 通过 gets 函数输入,可以输入带有空格的字符串,语法更简单
char str2[20];
gets(str2);

// 2.字符指针
// 2.1 通过 scanf 函数输入,需要先分配内存空间
char* str1 = (char *)malloc(sizeof(char)*20);
scanf("%s", str1);
// 2.2 通过 gets 函数输入,需要先分配内存空间,可以输入带有空格的字符串,并且语法更简单
char* str2 = (char *)malloc(sizeof(char)*20);
gets(str2);

gets()scanf() 的主要区别是:

  • scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。
  • gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,所以,不管输入了多少个空格,只要不按下回车键,对 gets() 来说就是一个完整的字符串。

也就是说,gets() 能读取含有空格的字符串,而 scanf() 不能。

注意:

  • 使用scanf函数输入字符串时,不需要指定&符号。如scanf("%s", &str);是错误的。因为数组名和字符指针名都表示地址。
  • 使用char *字符指针声明字符串时,需要先分配内存空间才能使用。

输出字符串

对于字符串的输出我们可以采用 printf 函数或者 puts 函数。

char str[]="hello world";

// 使用 printf 函数输出字符串,需要指定格式控制符 %s
printf("%s", str);

// 使用 puts 函数输出字符串
puts(str);

printf 函数和 puts 函数的主要区别是:

  • puts():专门用来输出字符串的,且只能输出字符串,输出字符串后自动换行。
  • printf():可以用来输出字符串,也可以输出其他类型的数据。通过格式控制符 %s 输出字符串,不能自动换行。

注意:

  • 无论是 printf 还是 puts 函数输出字符串时,都只需要传入字符串名就可以了。

访问字符串中的字符

无论是字符数组声明的字符串还是字符指针声明的字符串,都可以通过下面两种方式进行访问:

  • 第一种,下标
// 字符数组声明的字符串
char str[20] = "hello world";
char c;
c = str[1];// e

// 字符指针声明的字符串
char *str = "hello world";
char cc;
cc = str[1];// e
  • 第二种,* 操作符
// 字符数组声明的字符串
char str[20] = "hello world";
char c;
c = *(str + 1);// 通过字符串名加下标的方式

// 字符指针声明的字符串
char *str = "hello world";
char cc;
cc = *(str +1);// 通过字符串名加下标的方式

注意:

  • 数组下标是从 0 开始的,从 len-1 结束的。通常 len 指字符串实际字符个数。
  • *(str + i) 中 str 表示字符串名,而 i 表示待访问字符的下标,从 0 开始。
  • *str 默认访问字符串的第一个字符,等价于 *(str + 0)
  • *(str +i) 中的括号是必须的。

修改字符串中的字符

只有字符数组声明的字符串才能通过下标的方式进行修改,而字符指针声明的字符是不允许被修改的:

// 通过下标进行修改
char str[20] = "hello world";
str[1]='m';// 直接通过下标访问重新赋值即可

// 通过 * 操作符进行修改
char str[20] = "hello world";
*(str+1)='m';// 通过字符串名加下标的方式通过 * 操作符访问然后修改

// 下面的代码是错误示范
char *str = "hello world";
str[1]='x';// 错误
*(str+1)='x';// 错误

为什么字符指针声明的字符串不能被修改呢?如 char *str = "hello world"; 中的 "hello world"本身默认是一个字符串常量,它的值不容修改,而 str 只是一个指针,指向该字符串的首地址,对指向的地址空间的值的改变是不允许的。

计算字符串的长度

在C语言中我们可以自己写代码计算字符串中实际字符个数,也又可以通过引入 #include <string.h> 中的 strlen() 函数来计算:

  • 第一种,自己写代码计算,根据 '\\0' 是字符串的结尾符
#include <stdio.h>

int main()
    char str[] = "hello world";
    int i=0;
    int len=0;// 记录字符串中实际字符数
    while(str[i]!='\\0')
        len++;
        i++;
    

  • 第二种,调用 strlen() 函数
#include <stdio.h>
#include <string.h>

int main()
    char str[] = "hello world";
    int len;
    len = strlen(str);
    printf("%d", len);

遍历字符串中的每个字符

对于遍历字符串中每个字符的需求是比较少的,通常遇到这种情况是在算法题中,我们需要明白字符串是以 '\\0' 字符结尾的,所以如果要遍历字符串就要根据它来进行循环操作。

对于字符数组表示的字符串的遍历,可以通过下标的方式来访问字符串中的字符。例如:

char str[20] = "hello world";
int i=0;// 下标,初始为0
while(str[i]!='\\0')
    printf("%c", str[i]);// 输出字符
    i++;// 注意,下标移向字符串的下一个字符

如果想要使用 for 循环,通常结合字符串函数 strlen() 一起使用,该函数用来获取字符串中的实际字符个数。如:char str[20]="hello world";中的实际字符个数是 11 个。

char str[20] = "hello world";
int len = strlen(str);// 获取字符串中的实际字符个数
for(int i=0; i < len; i++)
    printf("%c", str[i]);

对于字符指针表示的字符串的遍历,既可以通过 * 符来访问字符串中的字符,又可以通过下标的访问来访问。例如:

char* str = "hello world";

// 1.使用下标的访问来访问遍历
int i=0;
while(str[i]!='\\0')
    printf("%c", str[i]);
    i++;


// 2.使用 * 操作符访问,但注意,字符串的指针也会向后移动
while(*str!='\\0')
    printf("%c", *str);
    str++;// 移动字符串指针


// 3.使用 * 操作符和下标的方式访问,字符串的指针可以不用移动
int i=0;
while(*(str+i)!='\\0')
    printf("%c", *(str+i));
    i++;// 只需要移动下标,而不需要移动字符串指针

注意:

  • 通常遍历字符串所有字符,采用 while 循环,而使用不等于 '\\0' 字符作为结束循环的条件。
  • 下标从 0 开始。
  • 无论是字符数组声明的字符串还是字符指针声明的字符串,都可以通过 strlen() 函数获得字符串中的实际字符个数。

以上是关于C语言零碎知识点之字符串的主要内容,如果未能解决你的问题,请参考以下文章

C语言零碎知识点之数据结构中的 *&

C/C++ 语言 零碎知识点的总结干货

C语言零碎知识点之定义指针时星号靠近类型名还是变量名

C/C++ 语言 零碎知识点的总结

C/C++ 语言 零碎知识点的总结

C/C++ 语言 零碎知识点的总结