跳转至

第十三章 字符串


字符串字面量

字符串字面量( string literal )是用一对双括号括起来的字符序列:

"Hello World"

字符串字面量中的转义序列

字符串字面量可以包含转义序列

"Hello\tWorld\n"

延续字符串字面量

字符串字面量可能太长,以至于无法放置在单独一行内可以把第一行用字符\结尾,那么C语言就允许在下一行延续字符串字面量:

printf("put a disk in drive A, then \
press any key to continue");

不只是字符串,字符\可以用来分割任何长的符号。

但\有一个缺陷:字符串字面量必须从下一行的起始位置继续,从而破坏了程序的缩进结构。

一个更好的办法是通过C语言的标准解决这个问题,也就是当两个或更多字符串字面量相连时(仅用空白字符分割),编译器必须把它们合并成单独一条字符串:

printf("put a disk in drive A, then"
       "press any key to continue\n");

如何存储字符串字面量

从本质上而言,C语言把字符串字面量作为字符数组来处理。当C语言编译器在程序中遇到长度为n的字符串字面量时,它会为字符串字面量分配长度为n+1的内存空间。+1存储的是额外的空字符,它用来标志字符串的末尾,用转义序列\0来表示,其数值为0。

例如,字符串字面量"abc"是一个有4个字符的字符数组:

字符串存储

字符串字面量可以为空。字符串""表示一个空串,仅有一个空字符。

既然字符串字面量是作为数组来存储的,那么编译器会把它看作是char*类型的指针。

字符串字面量的操作

通常情况下可以在任何C语言允许使用char*指针的地方使用字符串字面量。例如:

char *p;
p = "abc"; /* 并非复制abc中的字符,而仅仅是使p指向字符串的第一个字符 */

char ch;
ch = "abc"[1]; /* C语言允许对指针添加下标,因此可以给字符串字面量添加下标 */

Warning

对于一些编译器而言,改变字符串字面量的内容可能会导致运行异常。因此不推荐这么做。

字符串字面量与字符常量

只包含一个字符的字符串字面量不同于字符常量。

字符串字面量"a"是指针,指向存放字符a以及后续空字符的内存单元。而字符常量'a'是一个整数。

字符串变量

C语言只要保证字符串是以空字符结尾的,任何一维的字符数组都可以用来存储字符串。

定义字符串变量的惯用法:

#define STR_LEN 80
char str[STR_LEN + 1]; /* 强调的事实是 str 可以存储最多80个字符 */

初始化字符串变量

字符串变量可以在声明时进行初始化:

char str[8] = {0}; /* 空字符串 */

char date1[8] = "June 14";

char date2[8] = {'J', 'u', 'n', 'e', '1', '4', '\0'};

char date3[] = "June 14"; /* 编译器自动计算长度 */

字符数组与字符指针

比如:

char date1[] = "June 14"; /* 字符数组 */
char *date2 = "June 14"; /* 字符串字面量的指针 */

任何期望传递字符数组或字符指针的函数都将接受这两种声明的 date 作为参数。

然而,需要注意,不能错误地认为上面两种 date 可以互换。两者之间有显著的差异:

  • 在声明为数组时,就像任意数组元素一样,可以修改存储在 date 中的字符。但不可以修改字符串字面量。

  • 在声明为数组时, date 是数组名。在声明为指针时, date 是变量,它可以指向其他字符串。

字符串的读/写

使用 printf 和 puts 函数来读写字符串。

使用 scanf 和 gets 函数来读字符串。但 gets 函数不安全。推荐使用 fgets 函数。

使用C语言的字符串库

C语言的运算符无法操作字符串,C语言的库函数为字符串的操作提供了丰富的函数集。这些函数的原型驻留在 string.h 头文件中。比如:

strcpy 函数可以拷贝字符串。

strcat 函数可以追加字符串。

strcmp 函数可以比较字符串。

strlen 函数可以取得字符串的长度。

字符串数组

比如:

char *planets[] = {
    "Mercury",
    "Venus",
    "Earth",
    "Mars",
    "Jupiter",
    "Saturn",
    "Uranus",
    "Neptune",
    "Pluto",
};

planets 数组的每一个元素是一个字符串的指针。

命令参数

运行程序时,经常需要提供一些信息给程序,这是命令行参数( command-line argument )。必须把 main 函数定义为含有两个参数的函数:

int main(int argc, char* argv[])
{

}

argc (参数计数)是命令行参数的数量(包括程序名本身,最少为1)。 argv ("参数向量")是指命令行参数的指针数组。 argv[0] 指向程序名, argv[n] 表示第n个参数。

argv[argc] 始终是一个空指针。

如果用户输入了下面的命令:

ls -l remind.c

那么 argc 和 argv 是:

  • argc: 3

  • argv: {"ls", "-l", "remind.c", NULL}