【问题标题】:How to seperate data from a file stream in c++如何在 C++ 中从文件流中分离数据
【发布时间】:2020-02-15 19:02:47
【问题描述】:

我刚开始在大学学习 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

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

【问题讨论】:

  • 嗯,根据输出,你已经把它们分开了。现在您需要对它们应用适当的操作。您可以使用switch 语句来区分操作。
  • 类似这样的东西:int result = 0; switch (symbol) { case '+': result = first_number + last_number; break; case '-': ... }
  • 回答您提出的确切问题:是的,有。但是如果你真的在问为什么你的程序不工作,这就是调试器的用途,这是一个学习如何使用它来一次运行你的程序、监控所有变量及其值的好机会随着它们的变化,并分析程序的逻辑执行流程。了解如何使用调试器是每个 C++ 开发人员必备的技能,没有例外。在调试器的帮助下,您应该能够快速找到此程序以及您编写的所有未来程序中的所有错误,而无需向任何人寻求帮助。
  • 是的,有办法。在互联网上搜索“c++ 计算器解析”。还可以在互联网上搜索“c++ expression evaluator”。
  • @SamVarshavchik 这就是我目前用来单步执行 while 循环的每个输出的方法,感谢您的建议

标签: c++ fstream sstream


【解决方案1】:

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


#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;
    }
}

干杯!

【讨论】:

    【解决方案2】:

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

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

    我先给你看一个基于你的原始草稿的更正版本:

    #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 的答案,他们甚至使用全局变量。对不起各位。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 2021-03-01
      相关资源
      最近更新 更多