今天看到了如下的一段程序,程序运行后得到的结果和我们需要的结果不一样。
#include <iostream>
using namespace std;
void main()
{
char name[10];
char age[2];
cout<<"姓名 ";
cin.getline(name,10);
cout<<"年龄 ";
cin.ignore();
cin.getline(age,1);
cout<<"姓名 "<<name<<" 年龄 "<<age
<<endl<<endl;
}
执行程序后会发现:年龄的输出是空的!
而当把 cin.getline(age,1)该为 cin.getline(age,2),若输入25,年龄的输出是5而不是2,而当把cin.ignore()注释掉,然后加上cin.getline(age,2),输出的结果才是对的。
我把这个问题做了如下分析:
分析1:
char name[10],age[2]这些是C字符串,或者成为字符串数组。它有一个很重要的准则就是:必须以"/0"结尾!它是以'/0'来判断字符串数组中数据结束的位置的。
对C字符串的赋值方法一般有两种:
(1)直接给它赋一个字符串:例如,char name[10]="kiwi";这种赋值方法会自动在C字符串末尾添'/0'.所以这里的name[10]在内存中是这样存储的:k i w i /0 /0 /0 /0 /0 /0 。但如果令:char name[10]="abcdefghijk";那么数组在内存中是这样存储的:a b c d e f g h i /0 。 不过这样的赋值会产生溢出的错误
(2)以数组的方式为它初始化:例如:name[0]='k';name[1]='i';name[2]='w';name[3]='i',name[4]='/0';必须要有name[4]='/0',否则会产生错误!
分析2:
cin.ignore()的意思是删除输入流中的首个字符。但这里遇到的情况与我们平时遇到的情况有些不同,cin.ignore()在输入流的上面,但是即使这样,它也要等到输入流中有字符后删除其首个字符,不管是在它上面输入字符还是在它的下面输出字符。
下面这段程序中
cout<<"姓名 ";
cin.getline(name,10);
cout<<"年龄 ";
cin.ignore();
cin.getline(age,2); //注意是2
cout<<"姓名 "<<name<<" 年龄 "<<age;
执行结果:
姓名 kiwi
年龄 25
姓名 kiwi 年龄 5
为什么年龄变成了5呢?因为先执行cin.getline(name,10),输入流中的kiwi都被name读走了,输入流中已经没有字符可以ignore了。所以cin.ignore()要等待输入流中出现字符的时候,删除其首个字符。也就是说,接下去执行cin.getline(age,2)的时候我们往输入流中输入流25,那么cin.ignore()就删除了输入流中的首个字符2,此时输入流中只剩下5了,存入了age中,而age[2]在内存中存储是这样的:5 /0 .
所以age的输出结果是5了。
再看一段程序:
cout<<"姓名 ";
cin.getline(name,10);
cout<<"年龄 ";
cin.ignore();
cin.getline(age,1); //注意是1
cout<<"姓名 "<<name<<" 年龄 "<<age;
执行结果:
姓名 kiwi
年龄 25
姓名 kiwi 年龄
为什么这里的年龄没有输出呢?其实道理和前面一样的,只不过当cin.ignore()删除了输入流中的2时,输入流中剩下5。但是cin.getline(age,1)只允许在age中存入一个字符,那么不会存入5,只会存入'/0'.所以输出是空的。