Using ifstream& as a reference parameter to an ifstream within another function?

Hello, I've gotten the apparently classic programming student problem of "here's a text file with a bunch of roman numerals, do math with them." My professor requires that we use this list of functions, and make our main function in a couple lines of calling other functions. I'm not allowed to use global variables, and my solution for each part must be in an individual function.

1
2
3
4
5
string dataInput() // this reads from a .txt file, included in the next code block
int romanToDecimal(char r) // takes in a roman numeral as an input, and outputs an integer. I got this bit working, but I'm including everything I can.
char get_Oper(ifstream&) // this is the main one I'm having issues with. The textbook we have doesn't cover this without getting far too advanced.
void calcRomans(int n1, int n2, char operand, int&) // inputs two integers and an operator. I'm mainly confused with the int& here, as it's implied in the assignment that it should be an output.
void printResult(int result) // this is where the int from calcRomans() is supposed to end up. 


So there's a lot of functions there. I have personally solved this in like, 80 lines of code in a single function, but that's not allowed on this assignment. Right now, I have the following set of code for the get_Oper function.

1
2
3
4
5
6
7
8
9
10
string dataInput() { //string data input
    ifstream fileInput; //opens file input stream
    fileInput.open("mp4data.txt"); //opens file

}
char get_Oper(ifstream&fileInput) {
    string testString;
    getline(fileInput, testString);
    cout << testString;
}


And finally, here's the text file. There's tons of whitespaces which is annoying, but I'll find a solution for that easily I'd imagine.

1
2
3
4
5
6
7
8
9
MCCXXVI   CV   +
MCCXXVI  MCCXXVI   /
V  I  -
MDCLXVI   III  *
DL DXXXXVIII   -
D  L  /
MDI   CXI   +
XXV    IIII   /
XI  CII  *


The goal is to take each line, get the roman numerals from that line, and do the operation that's listed last. I can work with that, my question is more about referencing an ifstream as a parameter for a function. I could be massively misunderstanding, but I don't think this is possible.

Edit: I've realized my mistake for the get_Oper function, as I need to use getline() instead of trying to directly convert, but I still don't get any output.
Last edited on
Better naming would help.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool openFile(ifstream &fileInput) {
    fileInput.open("mp4data.txt"); //opens file
    return fileInput.is_open();
}

string &getExpression(ifstream &fileInput) {
    string testString;
    getline(fileInput, testString);
    return testString;
}

int main ( ) {
    ifstream in;
    if ( openFile(in) ) {
        string expr = getExpression(in);
        cout << "First line=" << expr << endl;
        istringstream is(expr);
        string lhs, rhs, op;
        is >> lhs >> rhs >> op;
    }
}

As each line element is separated by at least one white-space, and there are always 3 elements per line, then you can simply get each by using stream extraction. Consider this which will open the file, read each line and display each part. For n1, n2 then simply convert roman to decimal, then perform the required operation and then display the result in roman. I'd suggest you need three functions - roman to dec, dec to roman and calc to calculate the result. Then something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <string>
#include <fstream>

std::ifstream& openFile(std::ifstream& ifs, const std::string& nam) {
	ifs.close();
	ifs.open(nam);

	return ifs;
}

std::istream& getData(std::istream& ifs, std::string& rnum1, std::string& rnum2, char& oper) {
	return ifs >> rnum1 >> rnum2 >> oper;
}

int toDec(const std::string roman) {
	// convert roman to dec
}

std::string toRom(int dec) {
	// convert dec to roman
}

int calc(int n1, int n2, char op) {
	// perform op on n1 and n2 and return the result
}

int main() {
	std::ifstream ifs;

	if (!openFile(ifs, "mp4data.txt"))
		return (std::cout << "Cannot open file\n"), 1;

	std::string rn1, rn2;
	char op;

	while (getData(ifs, rn1, rn2, op))
		std::cout << "Result is " << toRom(calc(toDec(rn1), toDec(rn2), op)) << '\n';
}

tacowo wrote:
int romanToDecimal(char r) // takes in a roman numeral as an input, and outputs an integer. I got this bit working, but I'm including everything I can.


With that function prototype? I don't believe you.
Topic archived. No new replies allowed.