很多知识,靠记忆很难掌握;只有实操过后,才会了然于胸。
开一贴记录一下输入输出。
强烈吐槽一下win10的IE,基本上敲了一大半的文章,竟然卡住了,也没保存,刷了一遍,丢失了好多。。。。。。
1.cin 遇到空白(包括空格、TAB、回车)就结束;回车会被丢弃。
char c1,c2;
cin>>c1;
cin>>c2;
cout<<c1<<" "<<c2;
//输入a[Enter]b[Enter]
//输出a b
//20200618 cin>>c1后,回车/space/tab还会留在缓冲区中(因为,如果紧着着调用cin.get()是可以得到分隔符的),之后cin>>c2后,应该会把缓冲区中的分隔符拿掉,读入新的字符。
2.cin.get
有三种格式,①无参形式,ch=cin.get()
②一参数,get(char ch)
②一参数,get(char ch)
①和②是等价的,可以从缓冲区中读取[Enter]、[Space]、[Tab]。
char c1, c2;
cin.get(c1);
cin.get(c2);
cout<<c1<<" "<<c2;
//输入:a[space]b
//输出:a[space][space]
③三参数,get(array_name, array_size, endchar)
输入结束条件:在缓冲区中遇到
endchar就不再读入,
endchar会留在缓冲区中;
对结束符的处理:不丢弃缓冲区中的
endchar
endchar一般是[Enter],可以接受[Space]和[Tab]
对于③这个函数,实际能读入的最大字符个数是array_size-1,保证至少有一位是留给'\0'。
//下面聊聊get(array_name, array_size, endchar)
char c1[10], c2[10];
cin.get(c1, 5, 'a');
cin.get(c2, 5, 'a');
cout<<c1<<endl;
cout<<c2;
//输入:12a12a
//输出:12[Enter]
//cin首先从缓冲区中读取12,遇到结束符'a'停止读取,'a'留在缓冲区中,c1是12;接下来,cin继续从缓冲区中读取数据,读到的第一个数据是结束符'a',停止读取,'a'继续留在缓冲区中,c2是空字符。
//如果要在c1获得字符后,使c2也能获得字符,则需要使用cin.ignore()丢掉'a'或者cin.get(char)读掉'a'。
3.cin.getline(array_name, array_size, endchar);
cin.getline(array_name, array_size, endchar)与cin.get(
array_name, array_size, endchar)的读取方式差不多,以endchar结束,可以读取空白字符([Space]、[Tab]、[Enter],只不过[Enter]一般作为结束符使用)。
cin.getline(array_name, array_size, endchar)与cin.get(array_name, array_size, endchar)的不同主要有两点:
①cin.getline(array_name, array_size, endchar)会丢弃最后的结束符,而cin.get(array_name, array_size, endchar)则不会。
②当输入的字符串超长时,cin.getline(array_name, array_size, endchar)会引起cin函数错误(设置fail标志位,cin.rdstate() & ios::failbit),后面的cin操作将不再执行;而cin.get(array_name, array_size, endchar)则不会引起错误,后面的cin会继续执行,会继续从缓冲区中读取数据。
关于第一个不同点的例子:
char c, a[10];
cin.getline(a, 5, 'a');
cin.get(c);
cout<<a<<endl;
cout<<c<<endl;
//输入:11a11
//输出:11[Enter]1[enter]
//cin.getline将结束符a丢弃
关于第二个不同点的例子:
char c, a[10];
cin.getline(a, 5, 'a');
cin.get(c);
cout<<a<<endl;
cout<<c<<endl;
cout<<(cin.rdstate() & ios::badbit) <<endl;
cout<<(cin.rdstate() & ios::failbit) <<endl;
cout<<(cin.rdstate() & ios::eofbit) <<endl;
//输入:11111a
//输出:1111[Enter][Enter]0[Enter]2[Enter]0[Enter]
//解析:cin.getline首先从缓冲区中读入array_size-1个字符,由于在endchar之前有超过array_size-1个字符,所以cin会报错,设置fail_bit位,因此,cin.get(char)不会读入字符。也因此,根据cout的输出情况,输出a数组中的字符后,会出现两个[Enter]。
//输入:1111a
//输出:1111[Enter][Enter][Enter]0[Enter]0[Enter]0[Enter]
//解析:a正常读入array_size-1个字符后,遇到结束符,不会报错,然后丢弃结束符‘a’,此时缓冲区中还有一个[Enter],这个[Enter]通过cin.get(char)会被c读取,也因此,在cout时,会出现3个[Enter]。
<--------------------------------------------------------------分割线-------------------------------------------------------------->
1、2、3讲到的都是iostream中的函数,接下来的4为<string>中的函数,5、6讲到的时<cstdio>中的函数。
4. istream& getline (istream& is, string& str, char delim='\n');
和cin.getline()类似,getline会读取数据一直到遇到delim(即结束字符endchar)或者文档结尾或者遇到错误。和cin.getline一致,getline也会读取delim,并丢弃掉。
string str1, str2;
getline(cin, str1, 'a');
getline(cin, str2, 'a');
cout<<str1<<endl;
cout<<str2<<endl;
//输入:11a[Enter]11a[Enter]
//输出:11[Enter]11
5. char* gets(char * str) 需要包含<cstdio>
向str所指向的字符数组(C风格)中读入字符。遇到换行符[Enter]停止或文件结尾,停止;但不会将换行符读入字符串,空字符null('\0')将会被自动加入到str的结尾。
函数成功后,返回值是str;如果读取失败,则返回空指针。
char ch1[20], ch2[20];
gets(ch1);
gets(ch2);
cout<<ch1<<endl;
cout<<ch2<<endl;
//输入:11a[Enter]11a[Enter]
//输出:11a[Enter]11a[Enter]
使用gets要注意字符越界的风险。gets和fgets还是有显著不同的。
6.int getchar(void) 需要包含<cstdio>
从标准输入中返回字符,返回的字符会被提升为int。如果达到文件末尾或者错误发生,则返回EOF,并且设置相关标志位。