簡體   English   中英

C ++ fstream,從文本讀取數據並執行數學運算?

[英]C++ fstream, reading data from text and preforming math operations?

我的智慧到此為止。 我正在用C ++寫一個程序,它將讀取一個文本文件,其中包含以下內容作為簡要示例:

+ 23 34
- 9 8
+ 100 1
* 8 7
^ 2 5
/ 45 8

讀取器將第一個操作數存儲為char類型,並根據檢索到的char調用一個函數以對這兩個數字進行運算,下面是一個示例函數。

void doDivision(ifstream &inFile) {
    char ch;
    int num1, num2;

    inFile >> ch >> num1 >> num2;
    cout << "Division     " << num1 << "    " << num2 << "    " << "Quotient " << "    " << num1/num2 << " Remain " << num1%num2  << endl; 
}

一件事是我不確定為什么參數是&inFile這個函數原型不是我制作的,但這是從書中得到的,也許這就是為什么我不能使它起作用。

這是我的主要功能:

int main()
{

ifstream inFile;
char ch;
int num1, num2;

inFile.open("math.txt");
if (inFile.fail())
{
cout << ch;
      cout << "The math.txt input file failed to open";
        return -1;
}


 while(inFile)
{
    switch (ch) {

    case '+':
        doAddition(inFile);
        break;
    case '-':
        doSubtraction(inFile);
        break;
    case '*':
        doMultiplication(inFile);
        cout << "debug " << ch;
        break;
    case '/':
        doDivision(inFile);
        break;
    case '!':
        doFactorial(inFile);
        break;
    default:
        cout << "Invalid Operation" << endl;

    }

    inFile >> ch;
}

inFile.close();
return 0;
}

所有這些共同產生以下意外結果

Invalid Operation 
Addition 3 34 sum 37 (wrong data in text file is 23 and 34)
subtraction 0 8 difference 8 (data in textfile is 9 and 8 respectively)

我將不知道如何處理這個問題,因為我以前從未使用過文件。

一個簡單的錯誤是,在while()循環內部,直到第一次通過循環后才調用inFile >> ch 嘗試修復該問題,看看是否有幫助。

另外, 阿尼凱特(Aniket)在回答中所說的是您需要注意的另一個問題。

簡而言之,您的循環應大致如下所示:

inFile >> ch;
while(inFile) {
    switch(ch) {
    case '+':
        ...
    }
    inFile >> ch;
}

並且您的功能應與此類似:

void doDivision(ifstream &inFile) {
    int num1, num2;

    inFile >> num1 >> num2;

    ...
}

由於您已經在main()執行inFile >> ch ,因此從邏輯上在doAddition()和其他方法中再次讀取它是錯誤的。

由於您已經發布了doDivision()方法並在其中讀取了ch字符,因此我假設您在doAddition()中也是如此。

還有你的輸出:

加法3 34的總和37(文本文件中的錯誤數據是23和34)

告訴我們所有內容-您已讀取1個字符(找到+ ),然后在doAddition()方法中讀取了另一個字符,-將2讀入了doAddition() ch ,然后讀取了334 .。

這實際上是錯誤所在。

解決方案:將doAddition()和所有其他函數更改為如下所示。

void doAddition(ifstream &inFile) {
    char ch;
    int num1, num2;

    inFile >> num1 >> num2;
    cout << "Addition of " << num1 << " and " << num2 << " = "<< (num1+num2) << '\n';
}

另外,在main()函數中:

while循環應如下所示:

while(inFile)
{
    inFile >> ch;
    switch (ch) {

    case '+':
        doAddition(inFile);
        break;
    case '-':
        doSubtraction(inFile);
        break;
    case '*':
        doMultiplication(inFile);
        cout << "debug " << ch;
        break;
    case '/':
        doDivision(inFile);
        break;
    case '!':
        doFactorial(inFile);
        break;
    default:
        cout << "Invalid Operation" << endl;

    }
}

您不會在第一次迭代中讀入ch 實際上,當您檢查文件打開沒有問題時,可以執行cout << ch; 盡管ch未初始化。 您可以簡單地移動inFile >> ch; while循環的頂部。

下一個問題是,在每個doSomething函數中,您都在執行inFile >> ch ,這將嘗試再次讀取操作字符。 但是,您的doSomething函數不需要知道ch ,因為該函數本身是根據ch的值選擇的。

這是我的寫法:

ifstream inFile("math.txt"); // You can specify the file name here
char op;
int left_operand, right_operand;

// Use extraction has while condition
while (inFile >> op >> left_operand >> right_operand) {
  switch (op) {
    // Pass operands to the relevant function
    case '+': doAddition(left_operand, right_operand); break;
    // ...
  }
}

// You do not need to close inFile, it will be closed when it goes out of scope
return 0;

理想情況下,有更好的方法可以執行建議的操作,但是如果您必須使代碼看起來像這樣並執行,那么適當的解決方案應該是這樣的:

#include <vector>
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

void doAddition(ifstream &inFile) {
    int num1, num2;

    inFile >> num1 >> num2;
    cout << "Addition of " << num1 << " and " << num2 << " = "<< (num1+num2) << '\n';   
}

void doSubtraction(ifstream &inFile) {
    int num1, num2;

    inFile >> num1 >> num2;
    cout << "Subtraction of " << num1 << " and " << num2 << " = "<< (num1-num2) << '\n';
}

void doMultiplication(ifstream &inFile) {
    int num1, num2;

    inFile >> num1 >> num2;
    cout << "Multiplication of " << num1 << " and " << num2 << " = "<< (num1*num2) << '\n';
}

void doDivision(ifstream &inFile) {
    float num1, num2;

    inFile >> num1 >> num2;
    cout << "Division of " << num1 << " and " << num2 << " = "<< (num1/num2) << '\n';
}

void doFactorial(ifstream &inFile) {
    int t1, t2;

    inFile >> t1 >> t2;

    //perform factorial here
}

void readToNextLine(ifstream& inFile) {
    string t1, t2;

    inFile >> t1 >> t2;
}

int main()
{
    ifstream inFile;
    char ch;
    int num1, num2;

    inFile.open("math.txt");

    if (inFile.is_open()){

        inFile >> ch;
        while (!inFile.eof())
        {
            switch (ch) 
            {

                case '+':
                    doAddition(inFile);
                    break;
                case '-':
                    doSubtraction(inFile);
                    break;
                case '*':
                    doMultiplication(inFile);
                    break;
                case '/':
                    doDivision(inFile);
                    break;
                case '!':
                    doFactorial(inFile);
                    break;
                default:
                    readToNextLine(inFile);
                    cout << "Invalid Operation" << endl;
            }
            inFile >> ch;
        }
            inFile.close();
    }
    else
    {
        cout << "The math.txt input file failed to open";
        return -1;
    }

    inFile.close();
    return 0;
}

這里需要注意幾件事:

其他人建議的某些解決方案則不考慮默認情況 ,因為這種情況只是簡單地讀了其余的行, 從而導致邏輯錯誤 ,這是沒人希望的。

現在,對於“更好”的通用解決方案,將所有內容都首先存儲為字符串,然后進行標記化,然后嘗試將適當的標記轉換為所需的類型輸出,將是更理想的選擇。

但是,正如我之前指出的,如果您希望遵循以前的代碼,那么這是合適的。

除非您感到受虐狂,否則幾乎可以肯定,一次讀取所有運算符和兩個操作數,然后執行該操作最簡單:

char operation;
int operand1, operand2;

while (infile >> op >> operand1 >> operand2) 
   switch(operation) {
       case '+': add(operand1, operand2); break;
       case '-': sub(operand1, operand2); break;
       case '*': mul(operand1, operand2); break;
       case '/': div(operand1, operand2); break;
   }

僅對於四個操作員,它可以按原樣運行。 如果您將擁有更多功能,最好使用指向函數的指針表:

typedef int (*op)(int, int);

op operators[UCHAR_MAX];

for (int i=0; i<UCHAR_MAX; i++)
    operators[i] = report_bad_operator;

operators['+'] = add;
operators['-'] = sub;
operators['/'] = div;
operators['*'] = mul;
// more operators here

while (infile >> operation >> operand1 >> operand2)
    operators[operation](operand1, operand2);

否則的明顯原因/時間將是處理非二進制運算符(即,不一定要使用兩個操作數的運算符)。

首先,您正在閱讀chr,然后為其分配值。

像這樣更改while循環:

while(inFile)
{
    inFile >> ch; // assign before reading
    switch (ch) {

    case '+':
        doAddition(inFile);
        break;
    case '-':
        doSubtraction(inFile);
        break;
    case '*':
        doMultiplication(inFile);
        cout << "debug " << ch;
        break;
    case '/':
        doDivision(inFile);
        break;
    case '!':
        doFactorial(inFile);
        break;
    default:
        cout << "Invalid Operation" << endl;
    }
}

並按以下方式更改doDivision函數:

void doDivision(ifstream &inFile)
{ 
    int num1, num2;

    inFile >> num1 >> num2; // your already read the arithmetic operator
    cout << "Division     " << num1 << "    " << num2 << "    " << "Quotient " << " 
}

首先,初始階段,您的ch變量未初始化。 它在循環的底部初始化。

嘗試添加:

 inFile >> ch;

在while循環之前。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM