您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
第三讲 从一个小程序说起(2)
发布时间:2021-05-10 23:12:28编辑:雪饮阅读()
要求:編寫一個程序,要求用戶輸入一串整數和任意數目的空格,這些整數必須位於同一行中,但允許出現在該行中的任何位置。儅用戶按下鍵盤上的“Enter”鍵時,數據輸入結束。程序自動對所有的整數進行求和並打印出結果
这个题目涉及的知识量还是有点多的,其具体实现如:
#include <iostream>
using namespace std;
int main()
{
int sum=0;
/*
cout 用于在计算机屏幕上显示信息
流插入运算符“<<”
*/
cout << "請輸入一串整數和任意數目的空格:";
int i;
/*
cin代表标准输入设备,使用提取运算符 ">>" 从设备键盘取得数据,送到输入流对象cin中,然后送到内存。使用cin可以获得多个从键盘的输入值
流提取运算符“>>”
這裏是循環從cin輸入流中讀取字符到i中
cin>>返回的是cin本身,一般cin本身不爲0,只有当遇到EOF输入时,返回值为0。
*/
while(cin>>i)
{
sum+=i;
/*
该调用形式为cin.peek() 其返回值是一个char型的字符,其返回值是指针指向的当前字符,但它只是观测,指针仍停留在当前位置,并不后移。如果要访问的字符是文件结束符,则函数值是EOF(-1)。
相当于只是看了一眼下一个字符,因此叫 peek
当字符常量为空格字符时,不能只输入两个单引号,还必须在两个单引号之间输入一个空格;不然编译的时候就报错
報錯如:
error C2137: empty character constant
执行 cl.exe 时出错.
*/
while(cin.peek()==' ')
{
/*
get 成员函数读取单个字符,包括任何白色空格字符(這裏用來將這個空格讀取掉)
cin>> 读取字符的缺陷:
它会忽略掉所有前导白色空格,所以使用 cin>> 就不可能仅输入一个空格或回车符。除非用户输入了空格键、制表符之外的其他字符
比如用戶輸入的只是123這樣的數字,則這裏不需要cin.get,cin>>i也能正常執行
再比如你這裏只輸入了空格,則程序會卡在cin>>i不繼續向下執行了
當然就算是你正常輸入像是123這樣的數字,最後還是要輸入一下換行符(回車)才可以
個人理解:遇到空格會結束:但是流cin不會結束
cin>>读入数据遇到空格结束;并且丢弃空格符(空格導致看似死循環的正解)
*/
cin.get();
}
/*
cin>> 语句读取用户输入的数据时,它会在遇到换行符时停止。换行字符未被读取,而是仍保留在键盘缓冲区中。
从键盘读取数据的输入语句只在键盘缓冲区为空时等待用户输入值
换行符('\n')
下一個字符如果是結束字符就跳出
*/
if(cin.peek()=='\n'){
break;
}
}
cout <<"結果是:"<<sum<<endl;
return 0;
}
在vc6++编译运行结果如:
請輸入一串整數和任意數目的空格:1 2 3 4 6 5 7 8 9 0
結果是:45
Press any key to continue
用cin.ignore清除键盘缓冲区
cin.ignore()的一个常用功能就是用来清除以回车结束的输入缓冲区的内容,消除上一次输入对下一次输入的影响。
那么实例如:
#include <iostream>
using namespace std;
int main()
{
char buf[20];
/*
cin.ignore()函数是C++标准输入流(cin)中的一个方法
它表示从输入流 cin 中提取字符,提取的字符被忽略,不被使用。而每抛弃一个字符,它都要进行计数
如果计数值达到 a(比如这里的a就是7),则cin.ignore() 函数执行终止;
那么相当于这里将会忽略掉7个字符(正如其函数名的中文翻译)
*/
cin.ignore(7);
/*
cin.getline函数会一次读取多个字符(包括空白字符)。它以指定的地址为存放第一个读取的字符的位置,依次向后存放读取的字符,直到读满N-1个,或者遇到指定的结束符为止。
若不指定结束符,则默认结束符为换行符,此函数并不保留结束符,它通过结束符确定结束,但不保存结束符,它用空字符来替换结束符。其语法为:
cin.getline(字符指针(char*),字符个数N(int),结束符(char));
*/
cin.getline(buf,10);
cout << buf << endl;
return 0;
}
编译运行结果如:
kasumi_ayani_hayabusa
ayani_hay
Press any key to continue
这里可以看到最后结果中右边hay就结束了,但是hay后面早都超过7个字符了,为什么也会被忽略?这是因为这里cin.getline的第二个参数我们传入的是10,也就是只读取了10个字符。而我们实际输入字符超过了10个。
赋值表达式的打印
一般打印都是打印一个变量或者某个表达式所产生的右值,但是也有一种特殊的例外,就是对赋值表达式的打印,这种的确一般不常见。
那么具体可以看看如下实例:
#include <iostream>
using namespace std;
int main()
{
char p;
/*
流插入运算符“<<”
*/
cout << "请输入一段文本:\n";
/*
该调用形式为cin.peek() 其返回值是一个char型的字符,其返回值是指针指向的当前字符,但它只是观测,指针仍停留在当前位置,并不后移。
如果要访问的字符是文件结束符,则函数值是EOF(-1)。
*/
while(cin.peek()!='\n'){
/*
有些人可能对这个不太了解,一般错误的认为这步是打印p=cin.get()的结果,一般错误的认为p=cin.get()的打印结果由于是赋值语句,那么赋值必定是成功的,怎么可能会有失败
所以认为这里的结果肯定永远是1或true,但是实际上并非这样,对于一个赋值语句的打印若右边值是布尔类型,则真假就由右边决定,而对于非布尔值的右边,那么只要不是0,都算真
而这种情况下若将该表达式用在条件判断,则的确是真,但是打印出来则就是这个右边值本身了
*/
cout << (p=cin.get());
}
cout << endl;
return 0;
}
编译运行结果如:
请输入一段文本:
kasumi
kasumi
Press any key to continue
cin.read与cout.write
cin.read函数可以从输入流中读取指定数目的字符并将他们存放在指定的数组当中
cout.write() 成员方法专用于向输出流缓冲区中添加指定的字符串
那么实例如:
#include <iostream>
using namespace std;
int main()
{
const int SIZE=50;
char buf[SIZE];
/*
流插入运算符“<<”
*/
cout << "请输入一段文本:";
/*
cin.read函数可以从输入流中读取指定数目的字符并将他们存放在指定的数组当中
read读取要注意,输入结束后按下回车不管用,此时再次输入ctrl+z然后再次回车即可
*/
cin.read(buf,20);
/*
gcount()方法返回最后一个非格式化的抽取方法读取的字符数。(不就是原样读取咯)
*/
cout << "字符串收集到的字符数为:"<< cin.gcount() << endl;
cout << "输入的文本信息是:";
/*
cout.write() 成员方法专用于向输出流缓冲区中添加指定的字符串
write(const char * s,streamsize n);
其中,s 用于指定某个长度至少为 n 的字符数组或字符串;n 表示要输出的前 n 个字符。
原来甲鱼这里的第二个参数是20,但是这样会输出一些莫名奇妙的字符出来(烫),
我认为原因应该是在上面定义SIZE长度的buf数组中超过cin.gcount()部分的都是没有被我们赋值,所以按默认的输出了。
当字符串指针没有初始化或者处理完一段字符串没有在结尾添加\0,在输出该字符串时都会把系统默认的“烫”输出出来,
比如你在一个a[30]的前两位存储了字母a和b,,如果你没有给a[2]赋值为\0,那么输出字符串时就会出现ab和28个烫
cout.write(buf,20);
*/
cout.write(buf,cin.gcount());
cout << endl;
return 0;
}
编译并运行结果如:
请输入一段文本:kasumi
^Z
字符串收集到的字符数为:7
输入的文本信息是:kasumi
Press any key to continue
求取一个非负数的平方根及控制输出精度
要实现这个需要用到sqrt函数对一个非负数求取平方根。
cout.precision()函数的返回值就是对cout输出设定前的有效位数,默认为6
那么具体实现如:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
/*
sqrt:
功 能: 一个非负实数的平方根
*/
double result=sqrt(3.0);
cout << "对3开方保留小数点后0-9位,结果如下:\n"<<endl;
/*
cout.precision:
是C++输出函数cout的一个格式控制函数,用以控制输出数据的精度(保留小数点后几位,不传参则默认控制输出为6位精度),
*/
/*
for(int i=0;i<=9;i++){
cout.precision();
cout<<result<<endl;
}
*/
/*
这里为什么要注释循环?这个循环根本就是没有用的,甲鱼把这个放在这里,我个人认为就是浪费时间,所以我注释了,然后下面只需要输出result一次即可
*/
cout<<result<<endl;
cout <<"当前的输出精度为:"<<cout.precision()<<endl;
return 0;
}
编译运行结果如:
对3开方保留小数点后0-9位,结果如下:
1.73205
当前的输出精度为:6
Press any key to continue
域宽
域宽就是控制输入与输入的字符宽度。
具体的实例如:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int width=4;
char str[20];
/*
流插入运算符"<<"
*/
cout << "请输入一段文本:\n";
/*
width:输入操作提取字符串的最大宽度比定义的域宽小1,这是因为在输入的字符串后面必须加上一个空字符。
如果所需的宽度比设置的域宽小,空位用填充字符填充。如果显示数据所需的宽度比设置的域宽大,系统输出所有位。
域宽设置仅对下一行流读入或流插入操作有效(所以下面的while循环中要不断的设置域宽),在一次操作完后被置0。
*/
cin.width(5);
while(cin>>str){
cout.width(width++);
cout << str <<endl;
cin.width(5);
}
return 0;
}
编译并运行的结果如:

这里会发现,运行结束后即便按了ctrl+z也不能使程序结束,因为这里没有处理键盘缓冲区的换行,在上一行输入结束后的换行,没有清理,而对于换行符
cin>> 语句读取用户输入的数据时,它会在遇到换行符时停止。换行字符未被读取,而是仍保留在键盘缓冲区中。
从键盘读取数据的输入语句只在键盘缓冲区为空时等待用户输入值
所以这里程序就感觉好像是卡在这里了。
关键字词:c++,域宽
上一篇:第二讲 从一个小程序说起
下一篇:第4讲-从另一个小程序接着说