嗨,我知道这可能听起来像是一个重复的问题,但我已经花了很多天才解决这个问题而无法找到解决方案。在我的代码中我有一个while(true)循环,在文件的末尾我有一个带有文件结束函数和break的if语句,但在输出中它重复了最后一个数字两次。
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main ()
{
int line=0;
ifstream infile; //INPUT input file stream
ofstream outfile; //OUTPUT output file stream
infile.open("inputPartb.txt");
if (! infile)
{
cout <<"Problem opening input file inputPartb.txt"<<endl;
return 1; //not successful
}
outfile.open("resultsPartb.txt");
if (! outfile)
{
cout <<"Problem opening output file resultsPartb.txt"<<endl;
return 1; //not successful
}
while (true)
{
double num1;
double num2;
int intnum1;
int intnum2;
char mathOperator;
double addition;
double subtraction;
double multiplication;
int division; //division is using remainders so float isnt needed
double power;
double remainder;
line = line +1;
//reading numbers from the file
infile >> num1 >> num2 >> mathOperator;
intnum1 = num1;
intnum2 = num2;
//if statement for addition
if (mathOperator == '+')
{
//one for both num1 and num2 being integers
if ((num1-intnum1==0)&&(num2-intnum2==0))
{
addition = num1+num2;
outfile << fixed<< setprecision(0)<< num1 << " + " << num2 << " = " <<addition <<endl;
}
//one for either num1 or num2 being a float
else
{
addition = num1+num2;
outfile << fixed << setprecision(4)<< num1 << " + " << num2 << " = " <<addition <<endl;
}
}
//if statement for subtraction
else if (mathOperator == '-')
{
//one for both num1 and num2 being integers
if ((num1-intnum1==0)&&(num2-intnum2==0))
{
subtraction = num1-num2;
outfile << fixed<< setprecision(0)<< num1 << " - " << num2 << " = " <<subtraction <<endl;
}
//one for either num1 or num2 being a float
else
{
subtraction = num1-num2;
outfile << fixed<< setprecision(4)<< num1 << " - " << num2 << " = " << subtraction <<endl;
}
}
//if statement for multiplication
else if (mathOperator == '*')
{
//one for both num1 and num2 being integers
if ((num1-intnum1==0)&&(num2-intnum2==0))
{
multiplication = num1*num2;
outfile << fixed<< setprecision(0)<< num1 << " * " << num2 << " = " <<multiplication <<endl;
}
//one for either num1 or num2 being a float
else
{
multiplication = num1*num2;
outfile << fixed<< setprecision(4)<< num1 << " * " << num2 << " = " << multiplication <<endl;
}
continue;
}
//if statement for division
//one for both num1 and num2 being integers
else if (mathOperator == '/')
{
if ((num1==intnum1)&&(num2==intnum2))
{
if (num2 == 0)
{
outfile << num1 << " / " << num2 << " = ERROR" <<endl;
cout << "ERROR encountered on line "<<line<<endl;
}
else if ((num2==0)&&(num1==0))
{
division = static_cast<int>(num1)/static_cast<int>(num2);
remainder = (static_cast<int>(num1) % static_cast<int>(num2));
outfile <<setprecision(0)<<fixed<< num1 << " / " << num2 << " = " << division<<"R"<<remainder<<endl;
}
else
{
division = static_cast<int>(num1)/static_cast<int>(num2);
remainder = (static_cast<int>(num1) % static_cast<int>(num2));
outfile <<setprecision(0)<<fixed<< num1 << " / " << num2 << " = " << division<<"R"<<remainder<<endl;
}
}
//one for either num1 or num2 being a float
else
{
if (num2 == 0)
{
outfile << num1 << " / " << num2 << " = ERROR" <<endl;
cout << "ERROR encountered on line "<<line<<endl;
}
else if ((num2==0)&&(num1==0))
{
division = static_cast<int>(num1)/static_cast<int>(num2);
remainder = (static_cast<int>(num1) % static_cast<int>(num2));
outfile <<setprecision(4)<<fixed<< num1 << " / " << num2 << " = " << division<<"R"<<remainder<<endl;
}
else
{
division = static_cast<int>(num1)/static_cast<int>(num2);
remainder = (static_cast<int>(num1) % static_cast<int>(num2));
outfile <<setprecision(4)<<fixed<< num1 << " / " << num2 << " = " << division<<"R"<<remainder<<endl;
}
}
}
//if statement for power
else if (mathOperator == '^')
{
if ((num1-intnum1==0)&&(num2-intnum2==0))
{
if ((num1 == 0)&& (num2 == 0))
{
outfile << num1 << " ^ " << num2 << " = " << "ERROR" <<endl;
cout << "ERROR encountered on line "<<line<<endl;
}
else
{
power = pow(num1 , num2);
outfile <<setprecision(0)<<fixed<< num1 << " ^ " << num2 << " = " << power <<endl;
}
}
else
{
if ((num1 == 0)&& (num2 == 0))
{
outfile << num1 << " ^ " << num2 << " = " << "ERROR" <<endl;
cout << "ERROR encountered on line "<<line<<endl;
}
else
{
power = pow(num1 , num2);
outfile <<setprecision(4)<<fixed<< num1 << " ^ " << num2 << " = " << power <<endl;
}
}
}
//else statement for something other than the listed choices
else
{
if ((num1-intnum1==0)&&(num2-intnum2==0))
{
outfile <<setprecision(0)<<fixed<<num1 << " " << mathOperator << " "<< num2 << " = ILLEGAL"<<endl;
cout <<"ILLEGAL operator encountered on line "<<line<<endl;
}
else
{
outfile <<setprecision(4)<<fixed<< num1 << " " << mathOperator << " "<< num2 << " = ILLEGAL"<<endl;
cout <<"ILLEGAL operator encountered on line "<<line<<endl;
}
}
if( infile.eof() ) break;
}
outfile.close();
infile.close();
return 0;
}
非常感谢任何帮助。
答案 0 :(得分:0)
eof-check是有问题的,原因有两个:
operator>>
将只使用这一个字符。但是,您的文件可能会被尚未使用的换行符终止,因此不会设置eof位。然而,下一次读取将失败(将设置失败和eof位,因此您的循环将退出),但是当您执行此操作时在评估您的值之后检查,您将重复上一次成功的操作再次,类似于1中所描述的。但是,这次你的循环 退出是因为设置了eof-bit ... 所以请检查一下:
while (true)
{
infile >> num1 >> num2 >> mathOperator;
if(!infile) // possible as ifstream offers a bool cast operator...
break;
// evaluate values now
}
可以使用eof()
,如果您想要更细粒度的处理,但也要检查fail()
:
while (true)
{
infile >> num1 >> num2 >> mathOperator;
if(infile.eof())
break;
if(infile.fail())
{
// report error
break;
}
}
一些旁注:
将浮点值与==
进行比较检查绝对相等性。但由于可能发生的舍入(我们的位数有限,因此精度也有限),这可能会严重失败。请查看here,特别是按照提供的链接。
此外,你有批次的重复代码,你应该真的避免。
你可以做的第一件事:
infile >> num1 >> num2 >> mathOperator;
if(!infile)
break;
int precision = num1 - intnum1 == 0 && num2 - intnum2 == 0 ? 0 : 4;
现在您可以在输出时使用精度:
outfile << fixed << setprecision(precision);
您可以立即完全放弃if
/ else
的大部分内容。即使你没有,你应该更喜欢这个:
addition = num1 + num2; // common code, keep outside!
if (/*...*/)
{
outfile << fixed << setprecision(0);
}
else
{
outfile << fixed << setprecision(4);
}
对于加法,减法和乘法,您可以提供常见的处理:
double result;
if(op == `+`)
result = num1 + num2;
else if(op == `-`)
result = num1 - num2;
else if(op == `*`)
result = num1 * num2;
else
goto OTHERS;
outfile << fixed << setprecision(precision) << num1 << op << num2 << '=' << result << endl;
continue;
OTHERS:
// do the rest...
好的,在任何人抱怨之前:你可能已经读过关于goto
是邪恶的。嗯,不,那不是真的。它本身并不邪恶,但你可以用邪恶的东西 - 比如斧头,你可以用它来砍伐木头,但你也可以用它来杀人......比较下面的内容(留下一些线条) ,所以没有有效的C ++!):
if(op == `+`)
else if(op == `-`)
else if(op == `*`)
// else
// ^ we leave it away entirely!
if(op == `+` || op == `-` || op == `*`) // we repeate the checks!
{
outfile << fixed << setprecision(precision) /* ... */;
}
else
{
// the LARGE block here has an additional level of indentation
// alternatively, we could have used continue in the if...
}
或者这个:
if(op == `+`)
else if(op == `-`)
else if(op == `*`)
else
{
// very LARGE block of code
continue; // this one, you miss easily!
}
// and the common code to the initial if's is located FAR away from the them...
老实说,goto
没有让代码更清晰吗?