c++ - 将 char 写入浮点形式时,如何防止程序进入无限循环?
问题描述
我做了一个 Newton-Raphson Method 程序。但我有一个问题。如您所见,“epsilon”和“x0”是浮点类型,当我尝试编写“a”或“b”之类的东西时,程序会发疯。我想阻止它。当发生这样的事情时,我想告诉用户“请输入一个数字”。
你能帮我解决这个问题吗?谢谢你。
代码如下:
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<locale.h>
#include<iostream>
#include<math.h>
#include<sstream>
#include <iomanip>
#include<time.h>
#define f(x) pow(x,5)-pow(x,4)-pow(x,3)+2*pow(x,2)
#define g(x) 5*pow(x,4)-4*pow(x,3)-3*pow(x,2)+4*x
using namespace std;
int main()
{
setlocale(LC_ALL,"turkish");
cout << "Problem 4" << endl << "---------" << endl << "Verilen y=(x^2)/(x+1) ve y=(x^3)/(x^3+2) fonksiyonlarının varsa kesim noktalarını bulan C programı\n" << endl;
float x0, x1, f0, f1, g0, epsilon;
int tahmin = 1, sinir=1000;
cout << setprecision(6)<< fixed;
bastan:
cout << "Epsilon değerini giriniz: "; //Pay attention here. My question is about here.
epsilonHata:
cin >> epsilon;
cout << endl;
hata:
cout << "İlk tahmin değerini giriniz: "; //Just like above, my question is about here too.
cin >> x0;
cout << endl;
bla bla...
}
解决方案
发生无限循环问题是因为cin
基础ifstream
期望 afloat
在您的情况下。通过不提供浮点数,cin
失败并发生奇怪的循环。更多信息在这里。
由于您无法控制用户并且您不希望程序在用户输入字符时中断,因此您可以将输入读取string
为float
. 这样,不会设置错误标志cin
。
然后,您应该将字符串转换为浮点数。atof
适合这个目的。
#include <iostream>
#include <string>
#include <cstdlib>
...
std::string epsilon_str;
std::cin >> epsilon_str;
double epsilon = atof(epsilon_str.c_str());
从以下文档atof
:
如果 str 中的第一个非空白字符序列没有形成刚刚定义的有效浮点数,或者由于 str 为空或仅包含空白字符而不存在此类序列,则不执行转换并且函数返回 0.0 .
其他一般编程问题
您包含很多标题。了解哪个功能或类需要什么是最佳实践。我假设您在需要时将它们包括在内,但如果您不使用
setprecision
,则没有理由使用#include <iomanip>
.使用
define
意味着简单地复制粘贴。编译器不知道你在做什么。请参阅以下示例。#define WRONG_MULTIPLY(a, b) a * b #define CORRECTED_MULTIPLY(a, b) ((a) * (b)) ... int wrong_result = WRONG_MULTIPLY(1 + 2, 3 + 4); // 11 int corrected_result = CORRECTED_MULTIPLY(1 + 2, 3 + 4); // 21
最佳实践是使用函数。这就是函数的目的。
int multiply(int a, int b) { return a * b; } ... int result = multiply(1 + 2, 3 + 4);
我为宏使用大写字母来吸引人们注意它们是宏。说真的,你不想处理编译器错误,原因是你不知道的宏。
在这一点上,我建议通过一个教程,比如这个来理解基本概念。建议不要使用
using namespace std;
。如果存在std::multiply
与您的函数具有相同签名(相同的输入-输出)的签名,则会在您不注意的情况下调用标准函数。有办法防止这种情况发生,但首先不知道发生了什么是问题所在。让编译器指导您,不要欺骗自己。代码的流程和标签的使用似乎很复杂。编写您将理解的代码,例如,两个月后。我建议将单独的功能分解为功能,例如
readFloat
等checkEpsilonValid
。在需要时声明变量。这样更容易遵循代码。此外,使用有意义的变量而不是两个字母的变量可以提高可读性,您甚至不需要稍后发表评论。
最后,请注意这
setprecision
会影响cout
整个程序。这是关于你是否关心的问题,但对于更大的项目,我建议使用printf("%.06f")
, 或"%.06g"
,然后在必要时刷新。
推荐阅读
- c# - Razor if else only TR 标签
- php - 获取上次查询中插入的记录/获取更改的行数(MySQL)
- django - python中从插入的字符串中删除特定字符的难题
- java - JFrame中的滚动窗格未显示
- javascript - JS str.split() 不适用于使用 Jquery 获取的数据?
- python - subprocess.Popen 和communicate() 不执行程序,而终端执行
- asp.net-core - 如何在 ASP.NET Core 中获取已提交的复选框
- html - 如果将大小调整回与页面加载时相同的大小,则引导列布局会在调整大小时中断
- python-3.x - 如何使用 DF.split 在 python 中拆分字符串
- spring - 类图对 Javers 的依赖需要 JDK9+