在C++中字符和字符串是不同的,字符用单引号括起来,字符串用双引号括起来,两者有什么不一样呢?看一下下面的示例:
cout << sizeof('A') << endl;
cout << sizeof("A") << endl;
可以看到字符'A'占一个字节,而字符串"A"占两个字节,这是因为在C++中都有一个结束字符'\0'会添加到字符串的尾部,这个字符不会输出,它的作用仅仅是告诉计算机当前字符已到达结尾,但它会占据字符串的一个字节,索引字符串“A"占两个字节。
同时要特别说明一下,在C++中,一个中文字符占两个字节,看:
cout << sizeof('A') << endl;
cout << sizeof("A") << endl;
cout << sizeof("爸") << endl;
所以要输出一个字符串中的中文字符,必须连续输出相应的两个字节信息。
字符数组的初始化方法
1.逐个字符对数组元素赋初始值,这种情况最多就可给所有字符赋值。
char a[6] = { 'a','b','c','d','e','f' };
char b[6] = { 'a','b','c' };
char c[6] = { 'a','b','c','d','e','\0' };
cout << a << endl; //对于字符数组,直接输出数组名就可以输出整个数组的内容
cout << b << endl;
cout << c << endl;
出现了一些状况,字符数组a[6]因为初始化时没有对最后一个字符初始化为结束标志字符'\0',所以计算机在输出数组内容时,没有找到字符串结束标志,所以就继续输出,导致后面”很烫“(出现了乱码);而字符数组b[6]只对前面3个字符赋值了,后面字符就被C++默认赋值为‘\0',没啥问题;而字符数组c[6]就把最后一个字符赋值为'\0'作为字符串结束标志。第一种方法虽然确实可以对字符数组进行初始化,但一般都不建议这么做,因为这种方法”很笨“,且要时刻关注最后一个字符是否被赋'\0'值,比较麻烦。
2.直接用字符串常量进行初始化。
char a[6] = { "baba" };
char b[] = { "BaBa" };
cout << sizeof(a) << ':' << a << endl;
cout << sizeof(b) << ':' << b << endl;
初始化时可以确定字符数组大小,也可以不确定大小,如果不确定大小,则该字符数组最终的大小由赋值字符串常量决定(其可见字符的数量+1)。当然,代码中的{}也可以省略不写。这种方法比较灵活方便,一般提倡用这种方法。
3.对于字符数组,也可以直接 cin>>数组名 键盘输入对其所有字符赋值,如下:
char a[6];
cout << "输入:";
cin >> a;
cout << "输出:" << a << endl;
如果我们要输入的字符串中存在空格、Tab键时,会出现什么情况:
可以看到,遇到空格时,计算机直接停止了读取数据,因为对于cin来说,空格、Tab键和回车都表示一个输入的结束,但如果我们要给字符数组的初始化赋值中包含空格字符或Tab键字符(一般不可能包含回车字符),应该怎么操作呢?
此时可以用 cin.getline()函数,其具体格式为:cin.getline(字符数组名,字符个数n)。对于该函数,只有遇到回车键时才表示输入结束;或者输入字符个数已达到n个,则输入也会结束,同时会在后面添加字符'\0'。
char a[6];
cout << "输入:";
cin.getline(a, 6);
cout << "输出:" << a << endl;
注意:如果选择用cin.getline函数来输入,就要尽量避免再使用cin函数了,因为两者混合使用的话,一不小心就可能会出现意想不到的问题。比如先用cin来读取输入的第一行的所有内容,紧接着用cin.getline来读取下一行的内容时,会发现cin.getline读不进数据。这是因为cin读到回车键(’\n')时就停止了,此时读取位置停留在'\n'这里,如果接下来再用cin都数据,cin会自动跳过'\n'字符读取数据;如果用cin.getline来读取数据,那么cin.getline不会跳过'\n',而是直接把‘\n'读取(回车键直接默认读取结束),再添加一个'\0'字符,最终cin.getline就得到了'\0'字符,相当于”读不进数据"。
4.字符数组本质上也是属于数组的,所以有关数组的所以初始化方法在字符数组上都能适用,这里就不再赘述。