新手提问,请教高手

hhdyl740922 2008-02-19 02:28:04
刚刚自学C++,日前在做一道习题时发现一个问题,因为对相关函数调用不是很了解,所以一直解决不了,特请教相关高手^-^

题目是要求编一个程序,求已知三个边长的三角形面积.程序如下:

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
cout<<"任意已知边长的三角形面积计算程序\n";
double a,b,c,s,S;
bool quit=false;
do {
cout<<"\n请分别输入三角形三边边长\n";
cout<<"a=";
cin>>a;
cout<<"b=";
cin>>b;
cout<<"c=";
cin>>c;
s=(a+b+c)/2;
if ((c>(a+b))==(b>(a+c))==(a>(b+c)))
cout<<"不满足任意两边之和大于等于第三边的要求,错误输入,终止计算\n";
else if (a<0||b<0||c<0)
cout<<"边长输入含有负数,终止计算\n";
else{
cout<<"\n周长C="<<s*2<<endl;
S=sqrt(s*(s-a)*(s-b)*(s-c));
cout<<"面积S="<<S<<endl;
}
char mh;
cout<<"\n需要退出计算程序吗?“Y”或“N”"<<endl;
cin>>mh;
if((mh=='y')||(mh=='Y'))
quit=true;
}
while(!quit);
return 0;
}

程序可以达到题目要求.但是发现有两个问题:
1.在输入三个边长a,b,c的数据时,如果误输入了一个非数字的字符,如g,回车后程序会进入死循环.
2.在判定是否需要退出那一段,如果当时输入两个以上字符,如GG再回车的话,程序进入死循环.

因刚看过几天书,教程刚学到基本控制结构,所以想请教高手指点:
1.陷入死循环的原因
2.如何解决那两个问题

万分感谢!
...全文
170 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xmu_才盛 2008-02-21
  • 打赏
  • 举报
回复
10楼的回答应该是正解,但是我还是不明白?
c语言的printf是向一个缓冲区写东西
但是c++的cout是可以向多个缓冲区中写入

但是 输入时 就是只能从一个缓冲区中读取东西吗?


貌似如此
hhdyl740922 2008-02-21
  • 打赏
  • 举报
回复
Type: WebException Message: 基础连接已经关闭: 接收时发生错误。 Source: System.Web.Services Stack: 在 System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request) 在 System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request) 在 System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) 在 CSDN.Community.Services.CSDNPassportLogin.InsideLoginWebService.UserLogin(String LoginName, String Password, String UserIP, String ClientKey, String& ErrorInfo, String& WarningInfo) 在 CSDN.Community.Services.CSDNUserLogin.CheckUserPassword(String userName, String password, String& error) 在 CSDN.Community.PointForum.WebControls.TopicManageViewPage.bt_Submit_Click(Object sender, EventArgs e) Type: IOException Message: 无法从传输连接中读取数据: 远程主机强迫关闭了一个现有的连接。。 Source: System Stack: 在 System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) 在 System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size) 在 System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead) Type: SocketException Message: 远程主机强迫关闭了一个现有的连接。 Source: System Stack: 在 System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) 在 System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)


不知道是我的网络问题还是服务器出了问题.多次结贴不成功(保证密码无误).
难道新手就该受到折腾?

参与此贴的朋友都会配分.下午再试过,不行晚上再来.

另请教版主,贴子加分是否每次一加就是100,而不能修改?如否,请指明如何去弄或给个链接.另上面所遇到结贴不成的原因也指教一二.谢了.
hhdyl740922 2008-02-21
  • 打赏
  • 举报
回复
履行承诺,配分结贴.luwenzu回复解释最清楚.其他朋友一并谢过.
hhdyl740922 2008-02-21
  • 打赏
  • 举报
回复
我的理解,因为变量a是固定,所以输入的数据会固定的存入a处.而不会另找地址写入
hai040 2008-02-20
  • 打赏
  • 举报
回复
cin接收错误输入时,会把错误输入保留在buf,
并把状态置fail,后面的cin都不会发生作用

int i = 0;
char c = 'a';
while(i == 0 && c == 'a')
{
cin>>i>>c;
//cin.clear();
//cin.ignore();
}

输入y时就会死循环
cin.clear()可以重置状态,cin.ignore()可以跳过(清空?)buf
hhdyl740922 2008-02-20
  • 打赏
  • 举报
回复
谢楼上指点,这两天去弄一本来看看.

一晚上就沉到第二页了,五楼的疑问,还是期待能有高手解释一二.
若无人指点一二,则于明日结贴配分.

再次感谢
大前置 2008-02-20
  • 打赏
  • 举报
回复
在cin> > <int/float> 时 如果我们输入一个字符 就会导致刷屏的结果 这是因为非数字字符无法被cin接收而一直停留在缓冲区,导致下一次cin时直接从缓存读数 但字符无法读取结果导致无限循环 这被很多人认为成库的bug

解决方法:

1> 在cin> > <int/float> 后加cin.ignore();cin.clear();

cin.ignore()方法cin.ignore(5,'c' ) 的是从输入流(cin)中提取字符,提取的字符被忽略(ignore),不被使用。每抛弃一个字符,它都要计数和比较字符:如果计数值达到5或者被抛弃的字符是'c',则cin.ignore() 函数执行终止;否则,它继续等待。它的一个常用功能就是用来清除以回车结束的输入缓冲区的内容,消除上一次输入对下一次输入的影响。比如可以这么用:cin.ignore(1024, '\n' );,通常把第一个参数设置得足够大,这样实际上总是只有第二个参数 '\n' 起作用,所以这一句就是把回车(包括回车)之前的所以字符从输入缓冲(流)中清除出去。
cin.clear用法如果输入发生错误发生,那么流状态既被标记为错误,你必须清除这些错误状态,以使你的程序能正确适当地继续运行。要清除错误状态,需使用clear()函数。此函数带一个参数,它是你将要设为当前状态的标志值。,只要将ios::goodbit作为实参。

2> 在cin> > <int/float> 后加fflush(stdin);(需要stdio.h) fflush(stdin)刷新标准输入缓冲区



建议你对输入处理再计算.下面是我修改你的代码,可以解决你上述问题:
在DEV_C++ 平台运行通过

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
cout <<"任意已知边长的三角形面积计算程序\n";
double a,b,c,s,S;
bool quit=false;
do {
cout <<"\n请分别输入三角形三边边长\n";
cout <<"a=";
cin>> a;
cout <<"b=";
cin>> b;
cout <<"c=";
cin>> c;
//*******防止输入非数字导致陷入死循环代码***********
cin.ignore();
cin.clear();
cin.sync();
//****************************
s=(a+b+c)/2;
if ((c> (a+b))==(b> (a+c))==(a> (b+c)))
cout <<"不满足任意两边之和大于等于第三边的要求,错误输入,终止计算\n";
else if (a <=0 ||b <=0 ||c <=0)
cout <<"边长输入含有负数,终止计算\n";
else{
cout <<"\n周长C=" <<s*2 <<endl;
S=sqrt(s*(s-a)*(s-b)*(s-c));
cout <<"面积S=" <<S <<endl;
}
char mh;
cout <<"\n需要退出计算程序吗?“Y”或“N”" <<endl;
cin>> mh;
if((mh=='y') ||(mh=='Y'))
quit=true;


//*******建议开始时初始化*********************
a=0;
b=0;
c=0;
s=0;
S=0;
//*********************************
}
while(!quit);
return 0;
}

taodm 2008-02-19
  • 打赏
  • 举报
回复
建议你用《C++ Primer》第四版,并且一定要买配套的习题解答。
hhdyl740922 2008-02-19
  • 打赏
  • 举报
回复
汗一个,原来顶楼是不算在楼层内的,更正上一贴头一句,谢过二楼三楼的回复.

另外非常感谢四楼给出的发贴技巧.

hhdyl740922 2008-02-19
  • 打赏
  • 举报
回复
多谢三楼四楼两位的回复.

我知道第一个死循环的表面原因是因为我将a,b,c定义为double,而输入g时,则是一个char数.因为好奇,所以想听高手说明下,
也就是说,在C++中,这种死循环属于什么类型?然后,在这个程序中,可否加入一个选择语句,用于判定如果c或S无值时,程序通过跳转语句来跳出这个死循环?
还是只能通过加入判断a,b,c是否为double型的语句才可以?如果是这样,请教下用什么最简单?

再有一引申出来的问题是:char型数据为单个字符,那么从键盘输入一个字符后,是否不需要回车确认就会默认输入完成?还是多出的这个字符会暂存起来,等待下一次输入的调用?而两个字符输入后的回车,其实是相当于"字符/回车/字符"?

另请问下,有什么适合自已学习,例子较多,解说详细些C++教程方面的书可以推荐给如我这样的新手?
baihacker 2008-02-19
  • 打赏
  • 举报
回复
发贴的时候注意上面的一排:
A B I U S A # .....
点那个#
然后选c/c++
这里在编辑区域里出现成对的标签
把代码放在标签内
taodm 2008-02-19
  • 打赏
  • 举报
回复
解决方法需要用到很后面的知识,建议你暂时放置,以后来解决。
新手,有太多其它需要学的东西了。
我现在写这类小程序时也仍然不考虑处理这种死循环问题。输入的时候自己小心一下即可。
HelloDan 2008-02-19
  • 打赏
  • 举报
回复
由于double与int/char类型是不同的造成的。用户自己保证输入的数据准确性,要不然就自己要写判断程序去判断确保数据的正确性。
第二个问题的,如果你输入GG,即不是Y/y,判断只取第一个G,即循环继续,第二个G就成了边长a。同样可归为第一个陷入死循环的原因
hhdyl740922 2008-02-19
  • 打赏
  • 举报
回复
另外,对程序的不足之处,肯请一并指出~

先行谢过~

程序是复制过来的,发出后发现位置发生了变化.谁能帮忙说明下如何操作或指点下发贴指南的去处~结贴时一并有分~
再次谢过~

65,176

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧