您的位置:首页 > 编程语言 > C语言/C++

C语言中的字符串

2015-08-17 07:43 477 查看
C语言利用字符串常量和字符串变量来便捷地处理字符串。

字符串常量

字符串常量是使用一对双引号括起来的字符序列,包括可打印字符和转义字符。在字符串字面量中使用数字转义序列时要小心,因为不同的编译器可能把转移序列分解为不同的字符集合。

对于无法在单独一行内放置的字符串常量 ,通过把第一行用字符
\
结尾,C语言允许在下一行延续该字符串常量。使用这种方法的缺陷是字符串常量必须从第二行的起始位置继续,这样势必会破坏程序的缩进结构。还有一种更加有效地方法,将一条长的字符串常量分割为多条字符串常量放置在多行中,因为C语言标准规定编译器会将仅用空白字符分割的多条字符串常量合并为单独一条字符串。

C语言将字符串常量作为字符数组存储,当C语言编译器遇到长度为
n
的字符串常量时,它会为其分配长度为
n+1
的内存空间,在字符串常量所有字符的末尾额外存放一个空字符
\0
。编译器将字符串常量看成是
char *
类型的指针,因此可以在任何使用
char *
的地方使用字符串常量,比较特殊的用法是可以为字符串常量添加下标,访问特定字符。

不要修改字符串常量。

/**************************************
* string_literal.c                   *
*                                    *
* C语言的字符串常量                  *
**************************************/

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

int main()
{
printf("1: This is a very very very very very very long string literal!\n");

printf("2: This is a \
very very very very very very \
long string literal!\n");

printf("3: This is a "
"very very very very very very "
"long string literal!\n");

size_t length = strlen("4: This is a very very very very very very \
long string literal!\n");

size_t i = 0;
for (; i < length; i++)
{
printf("%c", "4: This is a very very very very very very \
long string literal!\n"[i]);
}

return 0;
}




字符串变量

C语言没有提供单独的字符串类型的变量,而是使用一维的字符数组存储字符串,该字符数组总是以空字符
\0
结尾的。因此在声明存放字符串的字符数组时,要保证字符串数组的长度总比字符串的长度多一个字符。用宏定义字符长度,用对宏加1的长度创建字符数组是常用的方法。

字符串变量的初始化就是一维字符数组的初始化,可以使用字符串常量来初始化一维字符数组。

char 数组名[] = 字符串字面量;


编译器将字符串常量看作是是最后一个字符为
\0
的一个初始化序列。如果字符串常量的长度比数组的长度短,则数组余下的元素都为空字符,如果字符串字面量的长度与数组长度相等,则将字符串字面量的字符赋值给数组,忽略
\0
字符,字符数组不再是字符串,如果字符串字面量的长度比数组长度长,则访问越界,是非法的。与声明一般数组一样,声明一维数组时也可以不指定长度,由编译器根据初始化的字符串字符量自动计算长度。

/**************************************
* string_var_init.c                  *
*                                    *
* C语言中字符串变量的初始化          *
**************************************/

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

#define STR_LEN 30

int main()
{
char hi[STR_LEN + 1] = "1: Hello World";
printf("%s\n", hi);

char hi2[] = "2: Hello World";
printf("%s\n", hi2);

printf("\"3: Hello World\"的长度为%u\n", (unsigned)strlen("3: Hello World"));

char hi3[14] = "3: Hello World";
int i = 0;
for (; i < 14; i++)
{
printf("%c", hi3[i]);
}
printf("\n");

return 0;
}




字符串的读写

可以利用
printf
函数使用转换说明符
%s
输出字符串,
printf
会逐个输出字符串中的字符直到遇到空字符为止。除了
printf
函数,C语言中还有另一个输出字符串的函数
puts
,它的原型为:

int puts(const char *str)


puts
函数只有一个参数,就是需要显示的字符串的指针。在输出完字符串后,
puts
函数会额外输出一个换行符,移到下一输出行的开始处。

可以利用
scanf
函数使用转换说明符
%s
读入字符串,
scanf
会跳过空白字符,从第一个非空白字符开始读入并将字符存储在字符串中直到遇到空字符为止,然后在读入字符的末尾添加一个空字符。由于输入的是字符串指针,不需要再使用取地址符
。除了
scanf
函数,C语言还提供了另一个字符串输入函数
gets
,
gets
函数的原型为:

char * gets ( char * str );


gets
函数不会在开始读字符串之前跳过空白字符,遇到换行符之外的空白字符也不会停止,直到遇到换行符。
gets
函数不会将换行符存储在字符串中,而是将其替换为一个空字符。
gets
puts
函数较为简单,因此速度比
printf
scanf
会更快。由于安全性考虑,
gets
函数已不建议使用,更安全的版本是
fgets


还可以利用
getchar
函数逐个字符读取字符串,可以更大程度地控制字符串的读入策略。

/*************************************
* string_print.c                    *
*                                   *
* C语言中字符串的输入和输出         *
*************************************/

#include <stdio.h>

#define STR_LEN 30

int main()
{
char str[STR_LEN + 1] = "";
puts("请输入你的名称: ");
scanf("%s", str);
printf("你好,%s\n", str);
printf("请输入你的国籍:\n");
getchar();
gets(str);
printf("你是%s人\n", str);

puts("输入你的ID,输入Tab结束");
char ch;
int i = 0;
char id[STR_LEN + 1];
do
{
ch = getchar();
if (ch == 'q')
break;
else
id[i] = ch;
i++;
}while(i <= STR_LEN);

id[i] = '\0';
puts(id);

return 0;
}




字符串的访问

由于字符串实际上是一个一维数组,因此可以用下标的方式访问,也可以用指针的方式访问。

/**************************************
* string_char_visit.c                *
*                                    *
* C语言访问字符串                    *
**************************************/

#include <stdio.h>

#define STR_LEN 60

int main()
{
char hi[STR_LEN] = "Good good study, day day up!";

int i = 0;
for (; i < STR_LEN; i++)
{
if (hi[i] == '\0')
break;
putchar(hi[i]);
}
printf("\n");

char *p = hi;
for(; p < hi + STR_LEN; p++)
{
if (*p == '\0')
break;

putchar(*p);
}
puts("");

return 0;
}




常用的C语言处理函数

C语言将字符串看作字符数组来处理,同数组的限制一样,没有提供支持字符串的复制、比较、合并和选择等操作的运算符。但C语言提供了丰富的函数库,支持这些操作。这些函数的原型存放在
string.h
文件中,使用这些函数前需要利用预处理命令包含该文件

#include <string.h>


strcpy
函数

strcpy
是字符串复制函数,原型为

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


该函数将
s2
指向的字符串复制给
s1
指向的字符串,该函数依次将
s2
中的字符复制到
s1
中直到遇到
s2
的一个空字符为止。要确保
s2
传入的字符长度不能超过
s1
的长度。返回值为目标字符串的指针
s1


strcat
函数

strcat
是字符串拼接函数,原型为:

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


strcat
函数将
s2
指向的字符串的内容追加到s1指向的字符串的末尾,并返回目标字符串的指针
s1
。要确保追加后的字符串的长度不超过
s1
的长度。

strcmp
函数

strcmp
函数用以字符串比较,其原型为

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


strcmp
依据字典中单词的编排顺序比较大小,返回负数表示
s1
指向的字符串小于
s2
指向的字符串, 返回0表示
s1
等于
s2
,返回正数表示
s1
大于
s2


strlen
函数

strlen
函数用以计算字符串长度,其原型为:

size_t strlen(const char *s);


strlen
函数返回第一个空字符前的字符个数。

/**************************************
* string_function.c *
* *
* C语言函数库中的字符串处理函数 *
**************************************/

#include <stdio.h>
#include <string.h>
#define STR_LEN 60

int main()
{
char str1[STR_LEN] = "";
char str2[STR_LEN] = "Hello World";

strcpy(str1, str2);
puts(str1);

char str3[STR_LEN] = ", Another World!";
strcat(str1, str3);
puts(str1);

int comp = strcmp(str1, str3);
printf("str1和str3的比较结果为%d\n", comp);

printf("str1的字符长度为%u\n", (unsigned)strlen(str1));

return 0;
}




字符串数组

可以通过创建二维的字符数组的方式来存储字符串数组,但是以这样的方式存储的话,对于不能够填满的字符都将用空字符填充,造成空间的浪费。因此可以利用指向字符串指针的方式存储数据,每个数组元素都是一个字符串指针,这样就不必限定每个数组元素的字符串的长度。

程序在运行时有时需要提供额外的信息,这些信息被成为程序参数或命令行信息。为了访问这些信息,必须把主函数定义为两个参数的形式:

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


argc
是命令行参数的数量,包括程序名本身,
argv
是指向命令行参数的指针数组,存放表示命令行参数的字符串。

/****************************************
* string_commandlinepara.c *
* *
* C语言的字符串数组存储命令行参数 *
****************************************/

#include <stdio.h>

int main(int argc, char *argv[]){
int i = 0;
for (i = 0; i < argc; i++)
printf("%d: %s\n", i+1, argv[i]);

return 0;
}




参考文献

K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社

http://www.cplusplus.com/reference/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: