我正在阅读Jesse Liberty的SAMS在10分钟内自学C ++并测试书中的示例。我发现代码中有一些关于文件i / o的错误,但我不知道它们在哪里。这本书没有提到任何关于它们的内容。我认为问题是由fstream
和catch(...)
引起的,但我不知道如何修复它。所以我想向有经验的C ++用户寻求帮助。
我不知道为什么程序在输入文件为空时始终会调用ErrorHandling::handleNotANumberError();
。
此外,当输入文件不存在时,程序有更多错误 。捕获异常并读取basic_ios::clear
。为什么会有错误?
当我删除有关例外的代码时,如果该文件不存在,它可以正常工作。
当我从空文件输入时,会出现“无效运营商”消息。
我认为无效的运算符是 eof字符。是吗?
我在谷歌搜索过但仍然无法弄清楚发生了什么。我知道下面的代码有点长,但我真的想知道会发生什么。
ifstream tapeInputStream; //global variable for callback
char getOperator()
{
char operatorInput;
if
(
tapeInputStream.is_open() &&
( !tapeInputStream.eof() )
)
{
tapeInputStream >> operatorInput;
}
else
{
cin >> operatorInput;
}
return operatorInput;
}
float getOperand()
{
float operandInput = 1;
if
(
tapeInputStream.is_open() &&
( !tapeInputStream.eof() )
)
{
tapeInputStream >> operandInput;
}
else
{
cin >> operandInput;
}
return operandInput;
}
void showResult( float theResult )
{
cout << endl << "Result: " << theResult << endl;
}
int main( int argc, char* argv[] )
{
if ( argc > 1 ) //a filename is present
{
try
{
tapeInputStream.exceptions( tapeInputStream.failbit ); //cin or ofstream?
tapeInputStream.open( argv[1], ios_base::in );
}
catch ( ios_base::failure &ioError )
{
ErrorHandling::handleInputStreamError( tapeInputStream, ioError );
//the stream will be unopened but the failbit will not be set
}
}
Calculator::aCalculatorExternalInterface CalculatorExternalInterface;
CalculatorExternalInterface.getAnOperator = getOperator;
CalculatorExternalInterface.getAnOperand = getOperand;
CalculatorExternalInterface.showResult = showResult;
int result = Calculator::calculateFromInput( CalculatorExternalInterface );
tapeInputStream.close(); //close the file to make output stream in tape() possible
Calculator::tape( '.', 0, argv[1] ); //stream and delete the tape
return result;
}
bool nextCalculation
(
const aCalculatorExternalInterface &theCalculatorExternalInterface
)
{
char operatorInput = theCalculatorExternalInterface.getAnOperator();
switch ( operatorInput )
{
case '.': //stop
return true; //done will become true
case '?': //show the tape
tape( operatorInput );
return false;
case '=': case '@': //no operand sent to accumulator
{
anOperator operatorValue =
( operatorInput == '=' ? query : reset );
float result = accumulator( operatorValue );
if ( operatorValue == query )
{
theCalculatorExternalInterface.showResult( result );
}
return false;
} //use curly brackets to define the scope
case '+': case '-': case '*': case '/': //calculation
{
float number = theCalculatorExternalInterface.getAnOperand();
anOperator operatorValue =
operatorInput == '+' ? add :
operatorInput == '-' ? subtract :
operatorInput == '*' ? multiply :
divide;
accumulator( operatorValue, number );
tape( operatorInput, number );
return false;
}
case '!': //self-test
selfTest();
return false;
default: //anythings else is an error
throw runtime_error( "Error: Invalid operator.");
}
}
int calculateFromInput
(
aCalculatorExternalInterface &theCalculatorExternalInterface
)
{
ErrorHandling::initialise();
bool done = false;
do
{
try
{
done = nextCalculation( theCalculatorExternalInterface );
}
catch ( runtime_error runtimeError )
{
ErrorHandling::handleRuntimeError( runtimeError );
}
catch (...)
{
ErrorHandling::handleNotANumberError();
}
}
while ( !done ); //continue when undone
return 0;
}
答案 0 :(得分:1)
我不知道抛出的异常是什么,所以我只添加一些if语句以防止由于空文件或不存在的文件而导致的任何错误。在问题出现问题之前处理问题可能会更好。(我对异常真的不太了解。)
以下是我在main.cpp中的新代码
if ( argc > 1 ) //a filename is present
{
try
{
tapeInputStream.exceptions( tapeInputStream.failbit );
if ( existFile( argv[1] ) ) //no need to read file if it does not exist
{
tapeInputStream.open( argv[1], ios_base::in );
if ( emptyFile() ) //no need to read file if it is empty
{
tapeInputStream.close();
}
}
}
catch ( ios_base::failure &ioError )
{
ErrorHandling::handleInputStreamError( tapeInputStream, ioError );
}
}
答案 1 :(得分:0)
在行catch ( ios_base::failure &ioError )
中,您只是处理一种类型的错误。尝试catch(...)
查看所有错误。请提一下运行代码后的其他错误是什么。
另外请确保您以正确的方式提供论据。
Executable<space>file_name_as_argument.