我有一个读取文件并返回文件中数字总和的函数。我正在检查文件是否存在。如果它不存在,我将返回1。但是我的问题是计算和的函数的返回值是int。因此,如果无法打开文件,它将返回1作为总和,而我希望它返回1作为错误指示符而不是总和。
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
int sum (string filename);
int main() {
string filename;
cout << "Enter the name of the input file: ";
cin >> filename;
cout << "Sum: " << fileSum(filename) << endl;
return 0;
}
int sum(string filename) {
int num = 0;
int sum = 0;
ifstream in;
in.open(filename.c_str());
if(!in.is_open()) {
cout << "Error opening " << filename << endl;
return 1;
}
in >> num;
cout << "File contains the values:" << endl;
while(in.good()) {
sum += num;
cout << num << " ";
in >> num;
}
if(!in.eof()) {
cout << "Error" << endl;
return 1;
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
这实际上取决于有效的输入(例如文件中的值)是什么,以及错误对程序的影响是什么(例如,如果不能计算总和,则程序是否可以明智地继续运行?)。
例如,如果你能保证在任何文件中的数据只包含正值,你可能会选择返回负值指示错误(例如-1,表示打开文件,出了问题-2,指示文件中的一个负值,-3以表示文件中的值之和大于可以存储在int等等中的值)。
不幸的是,如果文件中可以包含任何一组值(正值和负值),则这种“某些返回值有效,其他返回值指示错误”不起作用。例如,如果1文件中可能存在单个值,则显然1不能用于报告错误。同样,如果正负混合使用,则没有特定值可以返回以指示错误。
在这种情况下,选项包括
函数仅返回错误指示符,并接受其他参数来保存结果
int DoSum(const std::string &file, int &sum)
{
/* return value of zero indicates a sum has been computed
other values indicate an error status
*/
}
Run Code Online (Sandbox Code Playgroud)函数返回一个包含两个值的数据结构
struct ReturnData
{
int sum;
int error_indicator;
};
struct ReturnData DoSum(const std::string &file)
{
}
Run Code Online (Sandbox Code Playgroud)函数返回总和,但在错误时引发异常
int DoSum(const std::string &file)
{
/* do calculations */
if (error_has_occurred)
throw some_appropriate_exception();
else
return calculated_sum;
}
Run Code Online (Sandbox Code Playgroud)前两种情况的优点是,如果错误对程序不重要,则调用者不需要执行任何操作,而相应的缺点是调用者会忘记检查是否已发生错误。
第三种情况的优点在于,如果某些调用者(或调用者的调用者等)未捕获到异常,则程序将终止而不是继续处理错误数据。其缺点是,如果错误条件不严重,则无论如何都将强制调用者捕获异常。
因此,通常来说,除非程序要继续执行,否则绝对不应该抛出异常,除非绝对必须纠正错误条件的原因。