Read data from a .txt file but skip over comments (lines starting with #) in C++

Hey Experts,

I'm writing a function to read data from a file while ignoring any comments (for purposes of this program, this is any line in the .txt file that starts with the # character).

The format of the .txt file is as follows:

# first line of comments
# second line of comments
10
9
---------
---------
---------
---------
---------
---------
---------
---------
---------
---------

So the function should print:

Comment detected: # first line of comments
Comment detected: # second line of comments
Rows detected: 10
Columns detected: 9

Instead, it prints:

Comment detected: # first line of comments
Comment detected: # second line of comments
10
Error: StringToInteger called on illegal number 9
---------

I can't figure out why it's printing the 10, but whatever the reason, it's taking the 10 out of the ifstream before I can read it into rows. Any ideas as to what I'm doing wrong?

Thanks so much.
void ReadConfig(Grid<int>& board, string configFile) {
	ifstream config;
	config.open(configFile.c_str());
	
	string comment, line;
	int rows, cols;
	
	if (config.fail()) {
		cout << "Read failed." << endl;
	} else if (!config.fail()) {		
		while (config.peek() == '#') {
			getline(config, comment);
			cout << "Comment detected: " << comment << endl;
		}
		
		getline(config, line);
		rows = StringToInteger(line); // StringToInteger does exactly what you'd expect it to
		cout << "Rows detected: " << rows << endl;
		
		getline(config, line);
		cols = StringToInteger(line);
		cout << "Columns detected: " << cols << endl;
		
		board.resize(rows, cols);
		
		for (int r = 0; r < rows; r++) {
			getline(config, line);
			
			for (int c = 0; c < cols; c++) {
				if (line[c] == '-') {
					board[r][c] = 0;
				} else if (line[c] == 'X') {
					board[r][c] = 1;
				}
			}
		}
	}
	
	DrawBoard(board, rows, cols);
}

Open in new window

adamrothmanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Infinity08Commented:
There's no need to use peek(). Something like below works a lot better :
while (getline(config, line)) {
  if (line[0] == '#') {
    std::cout << "Comment detected: " << line << std::endl;
    continue;
  }

  // this is a non-comment line - treat it as such
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
adamrothmanAuthor Commented:
Thanks for the suggestion!

I don't want to loop over the entire file, though. Ideally I'd like to have some loop that, when it detects a comment line, consumes that line and checks the next line. After that loop I'll read into rows and cols, and parse the rest of the file.
0
Infinity08Commented:
You can easily adapt the code I posted for that :)
while (getline(config, line) && (line[0] == '#')) {
  std::cout << "Comment detected: " << line << std::endl;
}

// this is a non-comment line - treat it as such

Open in new window

0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

adamrothmanAuthor Commented:
Also, I tried using the code below, as suggested, but instead of printing

Comment detected: # first line of comments
Comment detected: # second line of comments
[first line after comments]
[second line]
etc...

it prints

Comment detected: # first line of comments
# second line of comments
[first line after comments]
[second line]
etc...
while (getline(config, line)) {
			if (line[0] == '#') {
				cout << "Comment detected: " << line << endl;
				continue;
			}
			
			cout << line << endl;
		}

Open in new window

0
Infinity08Commented:
Could you post the input file you're using for that ? Attach it to your post.
0
adamrothmanAuthor Commented:
Here it is.

Thanks again for your help. :)
config.txt
0
phoffricCommented:
I was curious as to why your peek did not seem to work. Your file uses '\r' as line delimiters. getline uses '\n' EOL delimiter by default. Here is reference on getline:
     http://www.cplusplus.com/reference/string/getline/

Try changing the getline LOC as follows:
       getline(config, comment, '\r');

That should help with this particular file.
0
Infinity08Commented:
>> Your file uses '\r' as line delimiters.

That's what I expected heh :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.