3.2 字符串(Strings of Characters)
迄今为止我们看到的程序都是使用的数字型变量(numerical variables)。但除了数字变量,还有字符串变量,我们可以用来表示连续的字符,如词,句子,名称,文本等等。到目前为止我们只是使用常量表示它们,其实我们还没有考虑过用变量来存储他们。
在C++ 中并没有一个单独的变量类型来专门存储字符串。为了完成这项功能,我们使用由连续字符(char)元素组成的字符数组。记住字符型数据(char) 是用来存储一个单个字符的,因此它的数组通常被用来存储字符串。
例如,如下数组(或字符串):
char jenny [20];
可以存储一个最多20个字符长的字符串。你可以把它想象成:
这20 个字符并不一定总是满的。例如,jenny 在程序的某一点可以只存储字符串"Hello" 或者"Merry christmas"。因此,既然字符数组经常被用于存储短于其总长的字符串,就形成了一种习惯在字符串的有效内容的结尾处加一个空字符(null character)来表示字符结束,它的常量表示可写为0 或'\0'。
我们可以用下图表示jenny (一个长度为20的字符数组) 存储字符串"Hello" 和"Merry Christmas" :
注意在有效内容结尾是如何用空字符null character ('\0')来表示字符串结束的。 后面灰的空格表示不确定数值。
字符串初始化(Initialization of strings)
因为字符串其实是普通数组,它与数组遵守同样的规则。例如,如果我们想将数组初始化为指定数值,我们可以像初始化其它数组一样用:
char mystring[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
在这里我们定义了一个有6个元素的字符数组,并将它初始化为字符串Hello 加一个空字符(null character '\0')。
除此之外,字符串还有另一个方法来进行初始化:用字符串常量。
在前几章的例子中,字符串常量已经出现过多次,它们是由双引号引起来的一组字符来表示的,例如:
字符串函数的头文件"the result is: "
是一个字符串常量,我们在前面的例子中已经使用过。
与表示单个字符常量的单引号(')不同,双引号 (")是表示一串连续字符的常量。由双引号引起来的字符串末尾总是会被自动加上一个空字符 ('\0') 。
因此,我们可以用下面两种方法的任何一种来初始化字符串mystring:
char mystring [ ] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char mystring [ ] = "Hello";
在两种情况下字符串或数组mystring都被定义为6个字符长(元素类型为字符char):组成Hello的5个字符
加上最后的空字符('\0')。在第二种用双引号的情况下,空字符('\0')是被自动加上的。
注意:同时给数组赋多个值只有在数组初始化时,也就是在声明数组时,才是合法的。象下面代码现实的表达式都是错误的:
mystring = "Hello";
mystring[ ] = "Hello";
mystring = { 'H', 'e', 'l', 'l', 'o', '\0' };
因此记住:我们只有在数组初始化时才能够同时赋多个值给它。其原因在学习了指针(pointer)之后会比较容易理解,因为那时你会看到一个数组其实只是一个指向被分配的内存块的常量指针(constant pointer),数组自己不能够被赋予任何数值,但我们可以给数组中的每一个元素赋值。
在数组初始化的时候是特殊情况,因为它不是一个赋值,虽然同样使用了等号(=) 。不管怎样,牢记前面标下画线的规则。
给字符串赋值(Assigning values to strings)
因为赋值运算的lvalue 只能是数组的一个元素,而不能使整个数组,所以,用以下方式将一个字符串赋给一个字符数组是合法的:
mystring[0] = 'H';
mystring[1] = 'e';
mystring[2] = 'l';
mystring[3] = 'l';
mystring[4] = 'o';
mystring[5] = '\0';
但正如你可能想到的,这并不是一个实用的方法。通常给数组赋值,或更具体些,给字符串赋值的方法是使用一些函数,例如strcpy。strcpy (string copy) 在函数库cstring (string.h) 中被定义,可以用以下方式被调用:
strcpy (string1, string2);
这个函数将string2 中的内容拷贝给string1。string2 可以是一个数组,一个指针,或一个字符串常量constant string。因此用下面的代码可以将字符串常量"Hello"赋给mystring:
strcpy (mystring, "Hello");
例如:
// setting value to string
J. Soulie
#include <iostream.h>
#include <string.h>
int main () {
char szMyName [20];
strcpy (szMyName,"J. Soulie");
cout << szMyName;
return 0;
}
注意:我们需要包括头文件才能够使用函数strcpy。
虽然我们通常可以写一个像下面setstring一样的简单程序来完成与cstring 中strcpy同样的操作:
J. Soulie
// setting value to string
#include <iostream.h>
void setstring (char szOut [ ], char szIn [ ]) {
int n=0;
do{
szOut[n] = szIn[n];
} while (szIn[n++] != '\0');
}
int main () {
char szMyName [20];
setstring (szMyName,"J. Soulie");
cout << szMyName;
return 0;
}
另一个给数组赋值的常用方法是直接使用输入流(cin)。在这种情况下,字符串的数值是在程序运行时由用户输入的。
当cin 被用来输入字符串值时,它通常与函数getline 一起使用,方法如下:
这里buffer 是用来存储输入的地址(例如一个数组名),length 是一个缓存buffer 的最大容量,而delimiter 是用来判断用户输入结束的字符,它的默认值(如果我们不写这个参数时)是换行符newline character ('\n')。
下面的例子重复输出用户在键盘上的任何输入。这个例子简单的显示了如何使用
// cin with strings
#include <iostream.h>
int main () {
char mybuffer[100];What's your name? Juan
Hello Juan.
Which is your favourite team? Inter Milan
I like Inter Milan too.
cout << "What's your name? ";
cout << "Hello " << mybuffer << ".\n";
cout << "Which is your favourite team? ";
cout << "I like " << mybuffer << " too.\n";
return 0;
}
注意上面例子中两次调用line 时我们都使用了同一个字符串标识 (mybuffer)。程序在第二次调用时将新输入的内容直接覆盖到第一次输入到buffer 中的内容。
你可能还记得,在以前与控制台(console)交互的程序中,我们使用extraction operator (>>) 来直接从标准输入设备接收数据。这个方法也同样可以被用来输入字符串,例如,在上面的例子中我们也可以用以
下代码来读取用户输入:
cin >> mybuffer;
这种方法也可以工作,但它有以下局限性是line所没有的:
• 它只能接收单独的词(而不能是完整的句子),因为这种方法以任何空白符为分隔符,包括空格spaces,跳跃符tabulators,换行符newlines和回车符arriage returns。
• 它不能给buffer指定容量,这使得程序不稳定,如果用户输入超出数组长度,输入信息会被丢失。
因此,建议在需要用cin来输入字符串时,使用line来代替cin >>。
字符串和其它数据类型的转换(Converting strings to other types)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论