Help with parsing a text file content and saving it to a vector

Hello,

I have written the same program using iostream, but now want to do it using fstream. Any STL container can be used.

I am trying to parse input from a file input.txt that contains:

List1 = 23, 30, 876, 24, 8934, 2131, 110, 437
List2 = 1, 3, 4, 6, 7

Output:
23
876
24
2131
110

I want to parse this file and store the content in 2 vectors, one vector for each list. Then print out the items in list1 in the order in list2.

List1 could have M elements, List2 could have N elements.


iostream version: Works like expected.

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 <vector>
#include <iostream>


using namespace std;


int main() {
    
    	vector<int> vec1;
	vector<int> vec2;
	int v1, v2, M, N;
	
	cout << "insert the size of the first vector" << endl;
	cin >> M;
	

	
	for (int i = 0; i <M; i++) {
		cout << "insert a value to be inserted in the first vector" << endl;
		cin >> v1;
		vec1.push_back(v1);
	}
	
	cout << "insert the size of the second vector" << endl;
	cin >> N;
	
	for (int i = 0; i <N; i++) {
			cout << "insert a value to be inserted in the second vector" << endl;
			cin >> v2;
			vec2.push_back(v2);
	}
	
	for (int i = 0; i < vec2.size(); i++) {
		int x = vec2[i];
		cout << vec1[x]<< endl;
	}
    return 0;
}


Fstream: This is where I am at :(

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
#include <fstream>
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
#include <stdlib.h> 
#include <cstdlib>

using namespace std;
 
int main() {
    ifstream myfile;
    vector<string> vec1;
	string input_string1;
    myfile.open("input.txt");
    if (myfile.is_open()) {
		int index1 = input_string1.find_first_of("=");
		input_string1 = input_string1.substr(index1 + 1);
		stringstream ss(input_string1);
		
		while(ss.good()) {
			std::string substring;
			std::getline(ss, substring, ',');
			vec1.push_back(std::atoi(substring));
		}
    }
    myfile.close();
    return 0;
}                 
             


Thank you,
Last edited on
An integer is not a list. std::list is a list. See http://www.cplusplus.com/reference/list/list/

The std::getline should store data into a std::string. See http://www.cplusplus.com/reference/string/string/getline/

String can prefill an std::istringstream. See http://www.cplusplus.com/reference/sstream/istringstream/

I would read from istringstream with formatted input and ignore the commas. See
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
http://www.cplusplus.com/reference/istream/istream/ignore/
I am trying to get them stored in lists, so I can manipulate the elements using iterators later on. Would I be able to do that if I store them in a string??
I edited the code.

Thanks,
Last edited on
A not so great way to parse a line in your format (but i've just knocked this up while eating my lunch).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <vector>
#include <sstream>

int main()
{
	std::vector<int> nums;
	std::string testString("List1 = 23, 30,876, 23, 8934, 2131, 110, 437");

        // remove the equals sign and stuff before this
	int index = testString.find_first_of("=");
	testString = testString.substr(index+1);
	std::stringstream ss(testString);

	while (ss.good())
	{
		std::string substr;
		std::getline(ss, substr, ',');

                // convert string to in and add to vector
		nums.push_back(stoi(substr));
	}
}


You will end up with a vector which you can use iterators with.

edit: changed to use stoi rather than atoi.
Last edited on
I altered the code in the original post. Still not working. Part of it is because my compiler does not support C++11 I think :(
1
2
vector<string> vec1;
vec1.push_back( std::atoi(substring) );

That's the message I'm getting now:

error: cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*' for argument '1' to 'int atoi(const char*)'

The substring is a std::string. There is no implicit conversion operator, but std::string has a member for explicit conversion:
http://www.cplusplus.com/reference/string/string/c_str/

vec1.push_back( std::atoi( substring.c_str() ) );
However, then you are attempting to add an int into vec1, that stores std::string objects.

// This can be called with a string:
1
2
3
4
5
6
7
8
9
10
std::vector<int> parseLine( std::istringstream ss ) {
  std::vector<int> result;
  ss.ignore( 30, '=' );
  int value;
  while ( ss >> value ) {
    result.push_back( value );
    ss.ignore( 1, ',' );
  }
  return result;
}
I think I did not know how to ask my question. I altered the original post and wrote an iostream version of the program I am trying to write using input from a file.

Thanks,
Josh
Note: Changing the original post too much makes a thread hard to follow, because the earlier comments suddenly refer to questions that cannot be seen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main() {
  std::string line;

  std::vector<int> list1;
  if ( std::getline( std::cin, line ) ) {
    list1 = parseLine( line );
  }

  std::vector<int> list2;
  std::ifstream myfile( "input.txt" );
  if ( std::getline( myfile, line ) ) {
    list2 = parseLine( line );
  }

  std::cout << '\n';
  std::copy( list2.begin(), list2.end(), std::ostream_iterator<int>( std::cout, " " ) );
  std::cout << '\n';
  std::copy( list1.begin(), list1.end(), std::ostream_iterator<int>( std::cout, " " ) );
  std::cout << '\n';
  return 0;
}
Ok i tried to compile this code, but it did not work:

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
#include <fstream>
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
#include <stdlib.h> 
#include <cstdlib>

using namespace std;
 
std::vector<int> parseLine( std::istringstream ss );
int main() {
  std::string line;

  std::vector<int> list1;
  if ( std::getline( std::cin, line ) ) {
    list1 = parseLine( line );
  }

  std::vector<int> list2;
  std::ifstream myfile( "input.txt" );
  if ( std::getline( myfile, line ) ) {
    list2 = parseLine( line );
  }

  std::cout << '\n';
  std::copy( list2.begin(), list2.end(), std::ostream_iterator<int>( std::cout, " " ) );
  std::cout << '\n';
  std::copy( list1.begin(), list1.end(), std::ostream_iterator<int>( std::cout, " " ) );
  std::cout << '\n';
  return 0;
}

std::vector<int> parseLine( std::istringstream ss ) {
  std::vector<int> result;
  ss.ignore( 30, '=' );
  int value;
  while ( ss >> value ) {
    result.push_back( value );
    ss.ignore( 1, ',' );
  }
  return result;
}
Ok I got this code to compile but no output :(

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 <fstream>
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
#include <stdlib.h> 
#include <cstdlib>

using namespace std;
 
std::vector<int> parseLine( string ss );
int main() {
  std::string line;
  std::ifstream myfile( "input.txt" );
  
  std::vector<int> list1;
  if ( std::getline( std::cin, line ) ) {
    list1 = parseLine( line );
  }

  std::vector<int> list2;
  if ( std::getline( myfile, line ) ) {
    list2 = parseLine( line );
  }

  for (int i = 0; i < list2.size(); i++) {
		int x = list2[i];
		cout << list1[x]<< endl;
	}
	
  return 0;
}

std::vector<int> parseLine( string testString ) {
                 
  std::vector<int> result;
  
  int index = testString.find_first_of("=");
	testString = testString.substr(index+1);
	std::stringstream ss(testString);
	int value;
  while ( ss >> value ) {
    result.push_back( value );
    ss.ignore( 1, ',' );
  }
  return result;
}
Explain the "did not work". Compiler errors? When posting a question to a Forum it is best to include as much details as possible. In the best case you might even spot the solution while gathering the details for a post.


Checking documentation:
The istringstream constructor is explicit. http://www.cplusplus.com/reference/sstream/istringstream/istringstream/
The explicit means that implicit calls are not allowed. Furthermore, copy constructor isn't there (I did not RTFM before scrambling code), so lets adjust that parseLine:
1
2
3
4
std::vector<int> parseLine( std::string str )
{
  std::istringstream ss( str );
  ...


http://www.cplusplus.com/reference/iterator/ostream_iterator/

The necessary library headers are:
1
2
3
4
5
6
7
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm> // std::copy
#include <iterator> // std::ostream_iterator 
It did not compile. I adjusted parseLine function already but still giving me this compile error:
17 Copy.cpp conversion from `std::string' to non-scalar type `std::istringstream' requested

This is the line:

list1 = parseLine( line );
Last edited on
The declaration of parseLine on line 11 is?
yes
I mean, the type of the parameter in it: string or istringstream?
I adjusted it to a string. Now I am able to compile the code but no output:

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
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm> // std::copy
#include <iterator> // std::ostream_iterator

using namespace std;
 
std::vector<int> parseLine( string str );
int main() {
  std::string line;

  std::vector<int> list1;
  if ( std::getline( std::cin, line ) ) {
    list1 = parseLine( line );
  }

  std::vector<int> list2;
  std::ifstream myfile( "input.txt" );
  if ( std::getline( myfile, line ) ) {
    list2 = parseLine( line );
  }

  std::cout << '\n';
  std::copy( list2.begin(), list2.end(), std::ostream_iterator<int>( std::cout, " " ) );
  std::cout << '\n';
  std::copy( list1.begin(), list1.end(), std::ostream_iterator<int>( std::cout, " " ) );
  std::cout << '\n';
  return 0;
}

std::vector<int> parseLine( string str ){
  std::istringstream ss(str);
  std::vector<int> result;
  ss.ignore( 30, '=' );
  int value;
  while ( ss >> value ) {
    result.push_back( value );
    ss.ignore( 1, ',' );
  }
  return result;
}
What do you have as input?
list1 = 121, 3, 46, 7685, 435, 8, 98, 45, 875, 3056
list2 = 1, 3, 4, 6
Ok I think I know why now. I had TWO files that have main function in the same workspace.
Last edited on
ABSOLUTELY FANTASTIC!

Thanks for all of you guys. I had two files that had main in the same workspace which stopped the output, even though the program was correct....

You guys have a wonderful day!!
Topic archived. No new replies allowed.