0

我刚开始在大学学习 c++,对于我们的第一个项目,我们被要求创建一个五函数计算器(+、-、*、/、%),它从文件中读取输入,对其执行算术运算并将其输出到屏幕。我得到一个输入文件,所有数字都像这样:

/   100     10
109.5 +     1.0
25    /     2
25.5  /     2
0     /     0
8     *     8
10    -    10
ab    -    ab
100   -     1
10    *   -10
10.5  +  1000
1000  -  1.05
1000  *  1000
1000  /  1000
1000  /     0

对于我的代码,这是我能想到的最好的:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;
const string file_name = "input.txt";


float calculate_number (float first_number, char symbol, float last_number);

int main () {
    ifstream input_file;
    ofstream output_file;

    // Open file to get input_file from
    input_file.open(file_name, ios::in);

    // Error checking
    if (!input_file) {
        cout << "Error: file input.txt does not exists\n";
        exit(1);
    } else {

        string data_from_file;           // Declare string to store data from file
        input_file >> data_from_file;    // Pass file content to data

        while (getline(input_file, data_from_file)) {
            istringstream ss(data_from_file);

            char symbol;
            int first_number, last_number;

            ss >> first_number >> symbol >> last_number;
            cout << first_number << symbol << last_number << endl;
        }
    }

    return 0;
}

上面的代码给出了以下输出,这是一团糟,但仍然向前迈出了一大步:

10010
109.5
25/2
25.5
0/0
8*8
10-10
0-10
100-1
10*-10
10.5
1000-1
1000*1000
1000/1000
1000/0

我的问题是,他们是否有一种方法可以将每个数字和算术运算符与输入流分开,将它们加在一起并将输出显示到屏幕上。提前致谢

4

2 回答 2

0

从输入文件中获取信息的最简单方法是在迭代从输入文件中获得的结果并将其传递给变量以便于参考时提取它。


#include <iostream>
#include <string>
#include <fstream>

using namespace std;
const string INPUT_FILE = "input.txt";
const string OUTPUT_FILE = "result.txt";


// Global variables

float first_number, second_number, answer;
char arithemetic_op;
ifstream input_file;     // File to get input from
ofstream output_file;    // File to put result in

// function prototype

float calculate (float first_number, char arithemetic_op, float second_number);


int main () {

    // Open file to get input_file from
    input_file.open(INPUT_FILE, ios::in);

    // Error if file does not exists
    if (!input_file) {
        cout << "Error: file `input.txt` does not exists\n";
        exit(1);
    }


    while (input_file >> first_number >> arithemetic_op >> second_number) {
        answer = calculate(first_number, arithemetic_op, second_number);

        output_file.open(OUTPUT_FILE, ios::out);
        output_file << first_number << " " << arithemetic_op << " " << second_number << " = " << answer << endl;
        output_file.close();
    }
    return 0;
}

float calculate (float first_number, char arithemetic_op, float second_number) {
    switch (arithemetic_op) {
        case '-':
            answer = first_number - second_number;
            return answer;
        case '+':
            answer = first_number + second_number;
            return answer;
        case '*':
            answer = first_number * second_number;
            return answer;
        case '/':
            answer = first_number / second_number;
            return answer;
    }
}

干杯!

于 2020-02-15T21:56:57.310 回答
0

你的方法基本上还不错。但是,您需要做更多的错误检查。还有一些语义错误。

始终检查输入/输出操作的结果是一条非常重要的规则。

我首先向您展示基于您的原始草稿的更正版本:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cmath>

using namespace std;
const string file_name = "r:\\input.txt";


float calculate_number(float first_number, char symbol, float last_number) {
    float result{ 0 };
    switch (symbol) {
    case '+':
        result = first_number + last_number;
        break;
    case '-':
        result = first_number - last_number;
        break;
    case '*':
        result = first_number * last_number;
        break;
    case '/':
        result = first_number / last_number;
        break;
    case '%':
        result = fmod(first_number, last_number);
        break;
    default:
        break;
    }
    return result;
}

int main() {
    ifstream input_file;
    ofstream output_file;

    // Open file to get input_file from
    input_file.open(file_name, ios::in);

    // Error checking
    if (!input_file) {
        cout << "Error: file input.txt does not exists\n";
        exit(1);
    }
    else {

        string data_from_file;           // Declare string to store data from file
        //input_file >> data_from_file;    // Pass file content to data

        while (getline(input_file, data_from_file)) {
            istringstream ss(data_from_file);

            char symbol;
            float first_number, last_number;
            // Rad data and check, if that worked
            if (ss >> first_number >> symbol >> last_number) {
                // Check for a valid symbol
                if ((symbol == '+') || (symbol == '-') || (symbol == '*') || (symbol == '/') || (symbol == '%')) {
                    cout << first_number << " " << symbol << " " << last_number << " = "
                        << calculate_number(first_number, symbol, last_number) << endl;
                }
            }
        }
    }

    return 0;
}

在学习更多 C++ 之后,您将使用以下解决方案。

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <numeric>
#include <map>
#include <utility>
#include <functional>

int main() {

    // All possible operations, defined in one place
    std::map<char, std::function<double(double,double)>> operation {
        {'+', std::plus<double>()},
        {'-', std::minus<double>()},
        {'*', std::multiplies<double>()},
        {'/', std::divides<double>()},
        {'%', static_cast<double(*)(double,double)>(std::fmod) }
    };

    // The file with the source data
    const std::string fileName{ "r:\\input.txt" };

    // Open the source file and check if it could be opened
    if (std::ifstream sourceStream(fileName); sourceStream) {

        // Read all lines of the source file
        for (std::string line{}; std::getline(sourceStream, line); ) {

            // For easier processing, put the line in a std::stringstream
            std::istringstream iss(line);

            // The operands and the operator
            double lhs{ 0.0 }, rhs{ 0.0 };
            char operationSymbol{};

            // Read the parts of the line and check, if read was OK
            if (iss >> lhs >> operationSymbol >> rhs) {

                // Now check, if we have read a valid operator
                if (operation.find(operationSymbol) != operation.end()) {

                    // Show the result
                    std::cout << lhs << " " << operationSymbol << " " << rhs << " = " << operation[operationSymbol](lhs, rhs) << "\n";
                }
                else std::cerr << "\n*** Error: Invalid operator '" << operationSymbol << "'\n\n";
            }
            else std::cerr << "\n*** Error: Problem while reading line:\n'" << line << "'\n\n";
        }
    }
    else std::cerr << "\n*** Error: Source file '" << fileName << "' could not be opened\n\n";

    return 0;
}

我很遗憾地说,但我不推荐用户 Onyrew 和 Tijana 的答案,他们甚至使用全局变量。对不起大家。

于 2020-02-15T22:10:18.920 回答