cin.ignore() is pausing my code reading data from a file

I'm trying to use cin.ignore after I use the extractor operator (>>) to read and discard the end of line character before I use a getline function to collect more data from an input file. Somehow cin.ignore() is pausing my code after it executes and I'm not sure why because I'm getting no error messages in the console. Why is this happening and how can I properly use cin.ignore() to discard the end of line character so that I can continue collecting data properly?


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
#include <iostream>
#include <fstream>
#include <limits>

struct test{
    std::string name;
    std::string location;
   std::string number;
   std::string movie;
   std::string color;
   std::string pet;
   std::string system;
}

  int main() {
  std::ifstream dataInput ("test.txt");

  test test[10];

  if (dataInput.is_open()) {
    int counter = 0;
    while (!dataInput.eof()) {
      dataInput >> test[counter].name;
      dataInput >> test[counter].location;
      dataInput >> test[counter].number;
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

      std::getline(dataInput, test[counter].movie);
      std::getline(dataInput, test[counter].color);
      dataInput >> test[counter].pet;
      dataInput >> test[counter].system;
      counter++;
    }
    dataInput.close();
  }
}


the test.txt file looks something like this:

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
mario
texas
2324234
star wars
purplish blue
dog
forest
mario2222
texas2222
2324234222
star wars22
purplish blue22
dog22
forest22
mario3333
texas333
232423433
star wars333
purplish blue333
dog333
forest333
mario444
texas444
232423444
star wars44
purplish blue44
dog44
forest444


Last edited on
Is this a joke? Your code doesn't make much sense. Where's the rest of the code? WTF is test???
Your input file is senseless, too.

Still, I assume your problem has to do with not checking for eof properly.
Doing this might fix it, but I'd need to see the rest of the code.

 
    while (dataInput >> test[counter].name) {

Last edited on
Sorry. test is just a struct. my actual code is a lot longer I just shortened it here to show only relevant parts. I edited my post to show that test is a struct. Does it make more sense now? The main trouble I'm having is finding out how to use cin.ignore to discard the end of line character after I use the extractor operator. I'm not getting any errors but it looks like my code just stops after cin.ignore is executed. To test this I put cout << "something" before and after the cin.ignore function is executed and only the cout message before cin.ignore is showing.
Last edited on
I was particularly confused by this line, but apparently you've removed it:

 
  dataInput >> test

And your input file is not very helpful, being gibberish.
For your input statements, you have 3 uses of >>, which read space-separated "words", so you would read in "han", "ds", and "mr", then you would skip the rest of that line (the " ds gt" part), then you read two whole lines, then two more space-separated words. It just seems strange.

Anyway, did you try what I suggested?
Hello icewizardwo323,

The problem is that std::cin.ignore(...) will clear the input buffer of what was entered by the keyboard, but you are reading from a file.

What you need is dataInput.ignore(...); to clear the file buffer.

Of course clearing the file buffer of the "\n" will not totally solve your problem. It appears that what you are trying to read does not match the input file.

Andy
Sorry I just edited my input file I think it will make more sense now. I tried your suggestion but that just breaks my code by collecting the data in an incorrect order, adding some weird values in, and cin.ignore is still pausing my code. This is pretty much all of my code by the way, it's just a struct and an input file. How might I not be checking for eof correctly? Is the way I'm using cin.ignore somehow messing up the eof?
Last edited on
Handy Andy thanks for your advice. That actually solved my entire problem. I really appreciate it.
Andy's spotted the main error! Read his post above. Although you also need to do what I said in order to test for eof properly.

that just breaks my code by collecting the data in an incorrect order

That doesn't make sense. It's exactly the same order (of course, don't read the name twice!!).
Last edited on
An alternative take is to overload the stream extraction (operator >>) to obtain a record from the file. Also, you don't need .ignore() in this case. Just use std::ws on the stream extraction to remove white space. Consider:

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
#include <iostream>
#include <fstream>
#include <string>

struct Test {
	std::string name;		// word
	std::string location;	// word
	std::string number;		// word
	std::string movie;		// line
	std::string color;		// line
	std::string pet;		// word
	std::string system;		// word
};

std::istream& operator>>(std::istream& is, Test& test)
{
	is >> test.name >> test.location >> test.number >> std::ws;
	std::getline(is, test.movie);
	std::getline(is, test.color);
	return (is >> test.pet >> test.system);
}

std::ostream& operator<<(std::ostream& os, const Test& test)
{
	// Extract to stream as required
	return (os << test.name << "  " << test.movie << "  " << test.location << "  " << test.pet);
}

int main()
{
	const size_t maxrec {10};

	std::ifstream dataInput("test.txt");

	if (dataInput.is_open()) {
		Test test[maxrec] {};
		size_t counter {};

		for (Test rec; (counter < maxrec) && (dataInput >> rec); test[counter++] = rec);
		dataInput.close();

		for (size_t t = 0; t < counter; ++t)
			std::cout << test[t] << '\n';
	} else
		std::cout << "Cannot open file\n";
}


which from the given data displays:


mario  star wars  texas  dog
mario2222  star wars22  texas2222  dog22
mario3333  star wars333  texas333  dog333
mario444  star wars44  texas444  dog44
Topic archived. No new replies allowed.