VectorLu

C 语言中的字符串详解

C 语言没有专门的字符串类型,要如何对字符串进行操作呢?其中又有哪些陷阱呢?

字符串字面量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
// 把字符串当作数组的操作
char digit_to_hex_char(int digit)
{
// 把 0-15 的数转换成等价的 16 进制数
return "012345689ABCDEF"[digit];
}
int main(void)
{
/*
* 字符串拼接
* 当两个或更多个字符串相邻时
* 仅用空白字符分割(不用逗号)
* 编译器会把它们合并成一个字符串
* 执行结果:
* hen you come to a fork in the road, take it. --Yogi Berra
*/
printf("When you come to a fork in the road, "
"take it. " "--Yogi Berra\n");
printf("%c\n", digit_to_hex_char(12));
return 0;
}

注意

不能改变字符串字面量的值,如下程序执行时产生错误 Bus error: 10。字符串字面量可能存在只读的区域。

1
2
3
4
5
6
7
8
9
#include <stdio.h>
int main(void)
{
char *p = "abc";
*p = 'd';
return 0;
}

字符串变量

C 中,只要保证字符串是以空字符结尾的,任何一维的字符数组都可以用来存储字符串。有时很难辨别是否把字符数组作为字符串来使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
// 惯用的字符串声明方法
#define STR_LEN 80
char str[STR_LEN+1];
int main(void)
{
/*
* 下面是两种相似的声明,均可作为字符串
* 但是两者不能互换
* 1. 声明为数组时,就像任意数组中的元素,可以修改 dateArray 中
* 的字符,dateArray 是数组名。
* 2. 声明为指针时,datePtr 指向字符串字面量,
* 字符串字面量是不可以修改的,datePtr 是变量,
* 可以在程序执行期间指向其他字符串。
* 如果希望可以修改字符串,那么就要建立字符数组来存储字符串
*/
char dateArray[] = "June 14";
char *datePtr = "June 14";
return 0;
}

另外,注意使用指针作为字符串变量之前必须把指针指向字符数组。或者让指针指向一个动态分配的字符串。

如果指针没有初始化,我们不知道它指向哪里,将其作为字符串时非常严重的错误。

1
2
3
4
5
6
char *p;
/*****WRONG******/
p[0] = 'a';
p[1] = 'b';
p[2] = '\0';

字符串的读写

换行符、空格符或制表符等会使 scanf() 停止读入,用 scanf() 读入的字符串永远不会包含空白字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
int main(void)
{
char str[10];
scanf("%s", str);
printf("%s\n\n", str);
return 0;
}
/* 执行结果
bash-3.2$ gcc basic.c
bash-3.2$ ./a.out
hi str
hi
bash-3.2$
*/

设计自己的输入函数

考虑如下问题:

  1. 在开始存储字符串之前,函数应该跳过空白字符吗?
  2. 什么字符会导致函数停止读取:换行符、任意空白字符还是其他某种字符?需要存储这类字符还是忽略掉?
  3. 如果输入的字符串太长以致无法存储,那么函数应该做些什么:忽略额外的字符还是把它们留给下一次输入操作?

注意手动加上 '\0'

1
2
3
4
5
6
7
8
9
10
11
12
int read_line(char str[], int n)
{
int ch, i = 0;
while((ch=getchar())!='\n' && ch!=EOF)
{
if (i < n)
{str[i++] = ch;}
}
str[i] = '\0';
return i;
}

使用 C 语言的字符串库

strcpy()

<string.h> 中的原型如下:

1
char *strcpy(char* s1, const char * s2);

函数把 s2 指向的字符串复制到 s1 指向的数组中。

您的支持将鼓励我继续创作!

热评文章