Splitting a String - Errors (expected primary-expression before ‘>’ token)

I've been reading solution #1 of:
https://www.fluentcpp.com/2017/04/21/how-to-split-a-string-in-c/
The particular code I'm referring to from ^ that post is:
https://gyazo.com/cd06f5120c9ab279478fc92cef5eeb52


This is my code so far that I tried to test but got errors 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
#include <iostream>
#include <string>
#include <vector>

// Will only be using for stuff I'm new to. Will make it easier
// to learn.
using namespace std;


int main() {
    int n;
	std::string userInLine;
    std::vector<std::string> userIn;

    std::cout << "[Debug] Please input the number of lines following: ";
    std::cin >> n;

    // for the number of lines that are going to be input:
    for (int i = 0; i < n; i++) {
	// Gets full line of input as one string.
	std::getline(std::cin, userInLine);
	// Splits string based off spaces in it.

	// iss is a variable of input string stream type.
	istringstream iss(userInLine);
	// a vector named results will have contents of split string.
	// [Not Done Yet] Can search through it for uppercase letter beginning b/c
	// that means it's a name not item name.
	vector<string> results(istream_iterator<string>(iss), istream_iterator<string>());

	std::cout << results[i] << ' ';
    }
    return 0;
}


These are the errors I got:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
test.cpp: In function ‘int main()’:
test.cpp:25:31: error: variable ‘std::istringstream iss’ has initializer but incomplete type
   istringstream iss(userInLine);
                               ^
test.cpp:29:26: error: ‘istream_iterator’ was not declared in this scope
   vector<string> results(istream_iterator<string>(iss),
                          ^~~~~~~~~~~~~~~~
test.cpp:29:49: error: expected primary-expression before ‘>’ token
   vector<string> results(istream_iterator<string>(iss),
                                                 ^
test.cpp:30:34: error: expected primary-expression before ‘>’ token
           istream_iterator<string>());
                                  ^
test.cpp:30:36: error: expected primary-expression before ‘)’ token
           istream_iterator<string>());
                                    ^

I tried the brackets solution as well (shown in the gyazo link) but it didn't work.

Any help would be greatly appreciated! Thanks!
Last edited on
right away I see that <sstream> is needed
You are missing two headers:
1
2
#include <iterator>
#include <sstream> 


Your line
vector<string> results(istream_iterator<string>(iss), istream_iterator<string>());
should (I think) be
vector<string> results(istream_iterator<string>{iss}, istream_iterator<string>{});
(Note the very subtle curly braces).

I fail to see what your line 31 is meant to achieve. It would output a single string out of a vector's worth of them.

Actually, I'm not sure this code would resolve what is asked in the question.
Last edited on
Apologies for the late reply. Thank you both for responding. I totally forgot about the headers, thanks for pointing that out.
- - -
@lastchance

Thanks for pointing out the brackets. I think when I tried doing it with the brackets before, I only put the brackets {} in the spot where it says {iss} not at the end.

"I fail to see what your line 31 is meant to achieve. It would output a single string out of a vector's worth of them."
It was for testing purposes. I wanted to see/make sure that the vector has the correct info in it. Also, because it is in the for loop it would go through and print for as many strings that were inputted (n). So I realize now that it wouldn't print the entire contents of the vector (like I intended) but it should've printed more than one (unless n = 1). In the latest version of my code, I have modified it a bit so it should print the entire vector.

"Actually, I'm not sure this code would resolve what is asked in the question. "
Do you know of any simpler ways to split a string? I'm still working on it, but I'm struggling to fully understand what is going on with line 29.

This is my latest code:
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
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <sstream>

// Will only be using for stuff I'm new to. Will make it easier
// to learn.
using namespace std;

int main() {
    // the number of lines that will be input
    int n;
    // the full line of user input:
	std::string userInLine;
    // declares the vecot results which will contain contents of split strings:
    vector<string> results;

    std::cout << "[Debug] Please input the number of lines following: ";
    std::cin >> n;

    // for the number of lines that are going to be input:
    for (int i = 0; i < n; i++) {
		// Gets full line of input as one string.
        std::getline(std::cin, userInLine);

        // iss is a variable of input string stream type.
		istringstream iss(userInLine);
		// a vector named results will have contents of split string.
	  	//vector<string> results(istream_iterator<string>{iss},
        results(istream_iterator<string>{iss},
				istream_iterator<string>{});
    }

    // Will go through the entire vector and print each part.
    std::cout << "[Debug] ";
	for (int i = 0; i < results.size()-1; i++) {
    //for (auto i = results.begin(); i < results.end(); i++) {
        std::cout << results[i] << ' ';
	}

    return 0;
}


But now I get this error:
1
2
3
test.cpp: In function ‘int main()’:
test.cpp:32:31: error: no match for call to ‘(std::vector<std::__cxx11::basic_string<char> >) (std::istream_iterator<std::__cxx11::basic_string<char> >, std::istream_iterator<std::__cxx11::basic_string<char> >)’
     istream_iterator<string>{});




Last edited on
It is unclear whether you are trying to split a single string or multiple lines.

If you want to continue as you are doing then on line 31 you need the insert() method of std::vector - you can look it up in the reference for this site. At the moment the statement is closer to the vector constructor.
@lastchance
I'm trying to split multiple strings one at a time.

For example: A user wants to input 2 lines.
Steps:
- User inputs 1st line.
- Program splits line into separate words based off the spaces in the string, then stores those separate words into a vector named results.
- User inputs 2nd line.
- Program splits line into separate words based off the spaces in the string, then stores those separate words into the results vector.

------------------------------------
I am struggling to understand how I should get the above code to work so I decided I'd try to create a completely separate program which will split the string using the information I already know in C++ (so without using any extra things like stream operator/iterator stuff..).

The program works for the most part but doesn't store the last word of the string into the vector.
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
Goal of this test program:
  - The user will input n number of lines/strings they plan to input.
  - Based off n, program will getline() for each string inputted. Then will break each string into parts (one at a time) and
    store those parts into a vector called results. It will break the string into parts based off the spaces in the string.
  - Next it will output the contents of the vector separated by a space.

Current Progress:
  - It will correctly store and add every part of the string EXCEPT the last word in the string.
    * For example, if I input: "This is Tommy" then it will store "This" and "is" but not "Tommy"
*/

#include <iostream>
#include <string>
#include <vector>

using namespace std; // only using for stuff I'm newer to.

int main() {
    char c;
    int n; // the number of lines (strings) that will be input
    std::string userInLine; // the full line of user input
    // declares the vector results which will contain contents of the split strings
    vector<string> results;

    std::cout << "[Debug] Please input the number of lines following: ";
    std::cin >> n;
    std::cin.ignore(1000, '\n');

    // for the number of lines (strings) that are going to be input:
    for (int i = 0; i < n; i++) {
        // Sets (or resets) to Starting Info:
        std::string tempString = "";
        int wordCount = 0;
        int oldWordCount = 0;
        bool firstTime = true;

	// Gets full line of input as one string.
        std::getline(std::cin, userInLine);
        std::cout << "[Debug] userInLine = " << userInLine << std::endl;
        
        // for each position in userInLine
        for (int pos = 0; pos < userInLine.size()-1; pos++) {
            c = userInLine[pos];
            if (c == ' ')
                wordCount++; // tells program to move to next position in
                                      // vector when inserting

            // if it has reached the last char in the string then do this.
            // For example: "This is Tommy", once it has "y" stored in tempString it does this part.
            else if (pos == userInLine.size() && (firstTime == true)) {
                results.push_back(tempString);
                pos--; // lets the most inner loop continue one more time so it can get to the else loop below.
                firstTime = false; // makes sure when it repeats one more time, it does not go into this else if part.
                wordCount++; // sets it up for next else part. Makes oldWordCount != wordCount.
            }

            // if we're checking a LETTER of a word & it's NOT the end of the string (the first time):
            else {
                // if we've moved to a new word:
                if (wordCount != oldWordCount) {
                    std::cout << tempString << '\n';
                    // Will push tempString word into results vector.
                    results.push_back(tempString);
                    // Makes wordCount & oldWordCount equal each other again.
                    oldWordCount = wordCount;
                    // Resets temp string:
                    tempString = "";
                }
                // add the char to the tempString
                tempString += c;
                //std::cout << "[Debug] tempString = " << tempString << '\n';
            }
        }
    }
    std::cout << "size of vector: " << results.size() << '\n';
    // Will go through the entire vector and print each part.
    std::cout << "[Debug] ";
	for (int i = 0; i < results.size()-1; i++)
        std::cout << results[i] << ' ';

    std::cout << '\n';

    return 0;
}
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
23
24
25
26
27
28
29
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;


void addToSplit( string line, vector<string> &allStrings )      // cumulatively add the strings in line
{
   stringstream ss( line );
   for ( string temp; ss >> temp; ) allStrings.push_back( temp );
}


int main()
{
// ifstream in( "input.txt" );
   stringstream in( "one two three four five\n"
                    "six seven eight nine ten\n"
                    "un deux trois quatre cinq\n"
                    "six sept huit neuf dix\n" );

   vector<string> allStrings;
   for ( string line; getline( in, line ); ) addToSplit( line, allStrings );

   cout << "Your words are (one per line):\n";
   for ( string s : allStrings ) cout << s << '\n';
}


Your words are (one per line):
one
two
three
four
five
six
seven
eight
nine
ten
un
deux
trois
quatre
cinq
six
sept
huit
neuf
dix



But you don't actually have to read it one line at a time. You can just do
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

int main()
{
// ifstream in( "input.txt" );
   stringstream in( "one two three four five\n"
                    "six seven eight nine ten\n"
                    "un deux trois quatre cinq\n"
                    "six sept huit neuf dix\n" );

   vector<string> allStrings;
   for ( string word; in >> word; ) allStrings.push_back( word );

   cout << "Your words are (one per line):\n";
   for ( string s : allStrings ) cout << s << '\n';
}




Finally, if you want to do it with stream iterators instead you could just do
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
using namespace std;

int main()
{
// ifstream in( "input.txt" );
   stringstream in( "one two three four five\n"
                    "six seven eight nine ten\n"
                    "un deux trois quatre cinq\n"
                    "six sept huit neuf dix\n" );

   vector<string> allStrings( istream_iterator<string>{ in }, istream_iterator<string>{ } );

   cout << "Your words are (one per line):\n";
   for ( string s : allStrings ) cout << s << '\n';
}
Last edited on
Thank you for the reply, I'm sorry I've responded so late. I was thoroughly confused, but we just went over the basics of streams in class and it makes more sense to me now. So with that, and the code you provided, I understand kinda how it works and how to do it.

Thanks!
Topic archived. No new replies allowed.