reading txt file; stringstream not advancing?

Im trying to read a text file that has strings separated by tab characters, each of these will be assigned to a variable. Then the process repeats for every line until there are no lines remaining.

Currently, I have set up a nested loop to read each string in. It loops the correct number of times (if 3 lines in file, it loops 3x), but the information that gets assigned each of these times is from the first line only. What am I doing wrong? Thank you

for example - the text file might say:
test1 test2 test3 test4
test5 test6 test7 test8
test9 test10 test11 test12

but my output is:
test1 test2 test3 test4
test1 test2 test3 test4
test1 test2 test3 test4

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
std::string item1, item2, item3, item4;
std::ifstream inFile;
std::string line, temp;
std::vector<std::string> tokens;
std::stringstream ss;

inFile.open("textfile.txt");
while (getline(inFile, line, '\n'))
{
	ss << line;
	while (getline(ss, temp, '\t'))
	{
		tokens.push_back(temp);
	}

	item1 = tokens[0];
	item2 = tokens[1];
	item3 = tokens[2];
	item4 = tokens[3];

	std::cout << item1 << '\n'
		<< item2 << '\n'
		<< item3 << '\n'
		<< item4 << '\n';
}


update: Upon further inspection, it looks like this is just pushing new items onto the vector - so the data from subsequent lines are not assigned correctly. But when I try to do tokens.pop_back() four times so that the vector is reset, it crashes the program for being out of range. It appears that the push_back() is only being done for one line.
Last edited on
Hello javascripty,

The problem is lines 16 - 19 and then line 21.

Even if you were to put 100 items in the vector lines 16 - 19 only assign "item1" - "item4" the same elements of the vector namely elements 1 - 3.

You would be better off to load your vector in the while loops and after the outer while loop create a for loop to display each element of the vector.

This would eliminate the need for "item1" - "item4".

Hope that helps,

Andy
Hello javascripty,

I found three problems:

First the input file was separated by spaces not tabs. So the std::getline(ss, temp, '\t') had nothing to find except when it reached the ens of the string stream.

Second I have most often seed the string stream defined inside the while loop. When I did this it worked.

Third you should check to see if the input opened correctly as you can see in the code below.

This is what I came up with:
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
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <chrono>
#include <thread>

int main()
{
	//std::string item1, item2, item3, item4;
	std::ifstream inFile;
	std::string line, temp;
	std::vector<std::string> tokens;

	inFile.open("textfile.txt");

	std::string inFileName("textfile.txt");

	if (!inFile)
	{
		std::cout << "\n File " << inFileName << " did not open" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(5));  // <--- Needs header files chrono" and "thread".
		return 1;
	}

	while (getline(inFile, line))
	{
		std::istringstream ss(line);
		//ss << line;

		while (std::getline(ss, temp, '\t'))
			tokens.push_back(temp);
	}

	for (auto it : tokens)
		std::cout << it << std::endl;

	// <--- Used mostly for testing in Debug mode. Removed if compiled for release.
	// <--- Used to keep the console window open in Visual Studio Debug mode.
	// The next line may not be needid. If you have to press enter to see the prompt it is not needed.
	//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue";
	std::cin.get();

	return 0;
}


Hope this helps,

Andy
That worked perfectly, thank you for the explanation as well
I'm bemused, @javascripty. Why don't you just do
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
   string item1,item2, item3, item4;
   ifstream inFile( "textfile.txt" );
   while ( inFile >> item1 >> item2 >> item3 >> item4 )
   {
      cout << item1 << " " << item2 << " " << item3 << " " << item4 << '\n';
   }
}

test1 test2 test3 test4
test5 test6 test7 test8
test9 test10 test11 test12
Topic archived. No new replies allowed.