Stay in file line count?

Hello everyone, I have a question for my c++ code. I have an assignment where I get have a file with different expressions to which I have to convert to post, pre, and in order. However, the prof. wants a menu option that every time the user choses to convert the expression, It only shows 1 at a time. So 1st conversion converts the first expression in the file, 2nd time the conversion option is called the second expression in the file is converted, etc. My question is, is there a way to keep the position of the getline within the file after returning the expression? I want to have a function that only gets the one expression in the file to then convert it to pre,post, and in order in a different function, but when I run the code again, the getline only gets the first expression. I would want it to continue to the next line in the file in order to get the next expression for converssion when the user decideds to print the next conversion. I hope this makes sense.

ExpressionsFile.txt:
x+y*a/b
y/x*b*a/x+x+a*b
x-b*a+c/y-a

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <fstream>
#include <iomanip>
#include <iostream>
using namespace std;

//Function Prototypes
void mainMenu();
void clearIn();
string getData();

int main() {
  mainMenu();
  return 0;
} 

void mainMenu(){
  enum option {PRINT = 1, EXIT = 2};
  int option = 0;

  while(option != EXIT){
    cout << "\nWelcome to The Expression Tree Menu\nPress:\n\n"
            "'1' - Print Expression in Post, Pre, and In order\n"
            "'2' - Exit Program\n"<<endl;
    cin >> option;

    switch(option){
      case PRINT:cout << '\n' << getData() << endl;break;

      case EXIT:break;

      default: clearIn(); break;
    }
  }
}

void clearIn() {//clears invalid inputs
	cin.clear();
	cin.ignore(numeric_limits<streamsize>::max(), '\n');
	cout << "\nInvalid input. Please try again.\n" << endl;
}

string getData(){
  string expression;
  ifstream inputFile;
  
// Checks for files Records to open successfully
  inputFile.open("ExpressionsFile.txt");
  if (!inputFile) {
		cout << "Input file not found. Quitting program." << endl;
		system("pause");
		exit(EXIT_FAILURE);
	}
  // Checks if the input file is empty
	if (inputFile.peek() == std::ifstream::traits_type::eof()) {
		cout << "\nWARNING: The input file is empty. Please add inputs for "
				"Validation\nEnding program..."
			 << endl;
		exit(EXIT_FAILURE);
	}

  if(!inputFile.eof()){//getline of the expression in file unless its at end of file
    getline(inputFile, expression);
  }

  return expression; //here I want it to return the first expression, then once getdata is called again, it goes to the next line in the file to get the next expression
}


-----------------
current output:

Welcome to The Expression Tree Menu
Press:

'1' - Print Expression in Post, Pre, and In order
'2' - Exit Program

1

x+y*a/b

Welcome to The Expression Tree Menu
Press:

'1' - Print Expression in Post, Pre, and In order
'2' - Exit Program

1

x+y*a/b

Welcome to The Expression Tree Menu
Press:

'1' - Print Expression in Post, Pre, and In order
'2' - Exit Program

1

x+y*a/b

Welcome to The Expression Tree Menu
Press:

'1' - Print Expression in Post, Pre, and In order
'2' - Exit Program

2


-------------------------
Desired output:

Welcome to The Expression Tree Menu
Press:

'1' - Print Expression in Post, Pre, and In order
'2' - Exit Program

1

x+y*a/b

Welcome to The Expression Tree Menu
Press:

'1' - Print Expression in Post, Pre, and In order
'2' - Exit Program

1

y/x*b*a/x+x+a*b

Welcome to The Expression Tree Menu
Press:

'1' - Print Expression in Post, Pre, and In order
'2' - Exit Program

1

x-b*a+c/y-a

Welcome to The Expression Tree Menu
Press:

'1' - Print Expression in Post, Pre, and In order
'2' - Exit Program

2
-------------------
I want to know if there is a way to do this without having to use a string array to which I have to store each expression individually to.
Thank you for your help.
your file keeps its position. it will just read the next line naturally.

if it does not you have done something to make this not work right; most likely reopened the same file again or something like that which would start over from the beginning. For example it looks like getdata function reopens every time.
instead of this, pass the file object into the function and keep the file object in main. Check that it is opened already in getdata, and if not, error out or ask for the file name...
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

// get the next line in the file. return false if there are no more lines to be read
bool get_next_line( std::string& line )
{
    // static local variables:
    //    initialised when this function is called for the first time, reused on subsequent calls
    static const std::string file_name = /* "ExpressionsFile.txt" ; */ __FILE__ ; // use this file for testing
    static std::ifstream file(file_name) ;

    return bool( std::getline( file, line ) ) ;
}

int main()
{
    std::size_t line_no = 1 ;
    std::string line ;
    while( get_next_line(line) ) std::cout << std::setw(3) << line_no++ << ". " << line << '\n' ;
}

http://coliru.stacked-crooked.com/a/15ae89a1c3e59a99
Perhaps 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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <limits>

void mainMenu();
void clearIn();
bool getData(std::string&);

int main() {
	mainMenu();
}

void mainMenu() {
	enum Option {
		PRINT = 1, EXIT = 2
	};

	for (int opt {}; opt != EXIT; ) {
		std::cout << "\nWelcome to The Expression Tree Menu\nPress:\n\n"
			"'1' - Print Expression in Post, Pre, and In order\n"
			"'2' - Exit Program\n\n";

		std::cin >> opt;

		switch (opt) {
			case PRINT:
				if (std::string exp; getData(exp))
					std::cout << '\n' << exp << '\n';
				else
					std::cout << "No data\n";

				break;

			case EXIT:
				break;

			default:
				std::cout << "Invalid option\n";
				clearIn();
				break;
		}
	}
}

void clearIn() {
	std::cin.clear();
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	std::cout << "\nInvalid input. Please try again.\n\n";
}

bool getData(std::string& exp) {
	static std::ifstream inputFile { "ExpressionsFile.txt" };
	static bool open {};

	if (!inputFile && !open)
		return (std::cout << "Cannot open file - "), false;

	open = true;
	return bool(std::getline(inputFile, exp));
}

Registered users can post here. Sign in or register to post.