[英]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
,然后读取了3
和34
.。
这实际上是错误所在。
解决方案:将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.