Opened csv and added functions, but unsure how to incorporate them into the code

Pages: 123
As I told you in a previous thread:

At line 18, you're creating a global variable called NHL. That variable is never used anywhere in your program, because you shadow it with, variously, local variables and function parameters, which usually have a different type from the global.

That global variable should be deleted.

As I told you in a previous thread, and others have told you in this one:

You really, really shouldn't use #include to include a .cpp file. You should set your project up so that the linker links the compiled object files together.

As I told you in a previous thread:

"Goalies" is a terrible name for a class that only stores a single goalie. You should rename it. Good naming is an important part of making your code understandable.

Why are we having to say the same things to you over and over again?
Last edited on
I've re-factored the code (needs C++17) as 1 file and used vector instead of an array. This will read the .csv file, display as read, display sorted by wins and then display by losses.

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <string>
#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;

class Goalies
{
public:
	// constructors
	Goalies();
	Goalies(const string& n, const string& t);
	Goalies(const string& n, const string& t, int w, int l, int ga, int sa);

	// implement setters
	void setName(const string& n);
	void setTeam(const string& t);
	void setWins(int w);
	void setLosses(int l);
	void setGoalsAllowed(int ga);
	void setShotsAgainst(int sa);

	// implement getters
	string getName() const;
	string getTeam() const;
	int getWins() const;
	int getLosses() const;
	int getGoalsAllowed() const;
	int getShotsAgainst() const;
	//double getSavePct() const;

private:
	//attributes
	string name;
	string team;
	int wins {};
	int losses {};
	int goalsAllowed {};
	int shotsAgainst {};
};

Goalies::Goalies() {}
Goalies::Goalies(const string& n, const string& t) : name(n), team(t) {}
Goalies::Goalies(const string& n, const string& t, int w, int l, int ga, int sa) : name(n), team(t), wins(w), losses(l), goalsAllowed(ga), shotsAgainst(sa) {}

void Goalies::setName(const string& n) { name = n; }
void Goalies::setTeam(const string& t) { team = t; }
void Goalies::setWins(int w) { wins = w; }
void Goalies::setLosses(int l) { losses = l; }
void Goalies::setGoalsAllowed(int ga) {	goalsAllowed = ga; }
void Goalies::setShotsAgainst(int sa) {	shotsAgainst = sa; }

string Goalies::getName() const { return name; }
string Goalies::getTeam() const { return team; }
int Goalies::getWins() const { return wins; }
int Goalies::getLosses() const { return losses; }
int Goalies::getGoalsAllowed() const { return goalsAllowed; }
int Goalies::getShotsAgainst() const { return shotsAgainst; }

vector<string> split(const string& s, char delim = ',')
{
	vector<string> tokens;

	const auto pb {[&](size_t st, size_t dp) {tokens.push_back(s.substr(st, dp - st)); }};

	for (auto delimPosition = s.find(delim), tokenStart = 0U; delimPosition != string::npos; )
		if (pb(tokenStart, delimPosition); (delimPosition = s.find(delim, (tokenStart = ++delimPosition))) == string::npos)
			pb(tokenStart, delimPosition);

	return tokens;
}

istream& operator>>(istream& is, Goalies& g)
{
	if (string line; getline(is, line))
		if (const auto tokens = split(line); tokens.size() >= 6) {
			g.setName(tokens[0]);
			g.setTeam(tokens[1]);
			g.setWins(atoi(tokens[2].c_str()));
			g.setLosses(atoi(tokens[3].c_str()));
			g.setGoalsAllowed(atoi(tokens[4].c_str()));
			g.setShotsAgainst(atoi(tokens[5].c_str()));
		}

	return is;
}

ostream& operator<<(ostream& os, const Goalies& g)
{
	return os << left << setw(25) << g.getName() << setw(15) << g.getTeam() << right << setw(4) << g.getWins() << setw(10) << g.getLosses() << setw(15) << g.getGoalsAllowed() << setw(15) << g.getShotsAgainst();
}

void showNames(const vector<Goalies>& goalies)
{
	cout << left << setw(25) << "Name" << setw(15) << "Team" << setw(8) << "Wins" << setw(8) << "Losses" << setw(15) << "Goals Allowed" << setw(8) << "Shots Against\n";

	for (const auto& g : goalies)
		cout << g << '\n';
}

int main()
{
	ifstream myFile("goalie_stats.csv");

	if (!myFile.is_open()) {
		cout << "Cannot open input file\n";
		return 1;
	}

	vector<Goalies> goalies;

	for (Goalies g; myFile >> g; goalies.push_back(g));

	// As stored
	showNames(goalies);

	// By wins
	sort(goalies.begin(), goalies.end(), [](auto a, auto b) {return a.getWins() < b.getWins(); });
	puts("\n");
	showNames(goalies);

	// By losses
	sort(goalies.begin(), goalies.end(), [](auto a, auto b) {return a.getLosses() < b.getLosses(); });
	puts("\n");
	showNames(goalies);
}


datafile:

Anthony Stolarz,TOT,4,5,50,503
Malcolm Subban,VEG,8,10,60,612
Cam Talbot,TOT,11,17,108,997
Linus Ullmark,BUF,15,14,109,1146
Semyon Varlamov,COL,20,19,136,1496
Andrei Vasilevskiy,TBL,39,10,128,1713
Cam Ward,CHI,16,12,115,1113


display

Name                     Team           Wins    Losses  Goals Allowed  Shots Against
Anthony Stolarz          TOT               4         5             50            503
Malcolm Subban           VEG               8        10             60            612
Cam Talbot               TOT              11        17            108            997
Linus Ullmark            BUF              15        14            109           1146
Semyon Varlamov          COL              20        19            136           1496
Andrei Vasilevskiy       TBL              39        10            128           1713
Cam Ward                 CHI              16        12            115           1113


Name                     Team           Wins    Losses  Goals Allowed  Shots Against
Anthony Stolarz          TOT               4         5             50            503
Malcolm Subban           VEG               8        10             60            612
Cam Talbot               TOT              11        17            108            997
Linus Ullmark            BUF              15        14            109           1146
Cam Ward                 CHI              16        12            115           1113
Semyon Varlamov          COL              20        19            136           1496
Andrei Vasilevskiy       TBL              39        10            128           1713


Name                     Team           Wins    Losses  Goals Allowed  Shots Against
Anthony Stolarz          TOT               4         5             50            503
Malcolm Subban           VEG               8        10             60            612
Andrei Vasilevskiy       TBL              39        10            128           1713
Cam Ward                 CHI              16        12            115           1113
Linus Ullmark            BUF              15        14            109           1146
Cam Talbot               TOT              11        17            108            997
Semyon Varlamov          COL              20        19            136           1496


You really, really shouldn't use #include to include a .cpp file. You should set your project up so that the linker links the compiled object files together.


I've done it this way because my professor requires that we send in the main file, .cpp file and .h file. I'm working on making the code into a menu where you select 1 to sort by wins, 2 for losses, and 3 to sort by goalie save percentage. Thanks for the help guys i'll let you know how it goes, i might try incorporating what you have seeplus, i haven't used a lot of what you used before so it's sort'eve confusing since i to put it into 3 files.
"Goalies" is a terrible name for a class that only stores a single goalie. You should rename it. Good naming is an important part of making your code understandable.



I'll rename the class Goalie and refer to it by "goalies", i don't understand a lot of the things you guys explain so that's why it seems like you're repeating it ig, also my 3 files total are opened in 1 project, but WE NEED TO SUBMIT 3 INDIVIDUAL FILES, my bad for not making it clear
I'm gonna restart my whole program, and use the headers my teacher just hinted to us since everyone was struggling lol, i'll keep you guys updated, thanks for the help


You have to create a Goalie class. This requires Goalie.h and Goalie.cpp.

Your main function will have an array of 100 goalies like this:
Goalie goalies[MAX_GOALIES];

It does not have to be an array of pointers. If you use it as above, then it automatically creates 100 goalie objects, each instantiated using the default "no args" constructor. Therefore when you read the .csv file you will need to use the "setter" functions to set the fields of each goalie.

Here are the functions in my main.cpp file, other than main():

void showMenu(); // show the menu
bool openFileIn(fstream &, string); // open the input .csv file
int readGoalies(fstream &, Goalie []); // read the goalies from the file into the array
int showGoalies(Goalie *, int); // show the goalies
void split(const string&, char , vector<string>& ); // tokenize the line from the file
void sortGoaliesByWins(Goalie goalies[], int size); // sort by wins
void sortGoaliesByLosses(Goalie goalies[], int size); // sort by losses
void sortGoaliesBySavePct(Goalie goalies[], int size); // sort by Save Pct
void swapGoalies(Goalie &a, Goalie &b); // swap, required for sorting
I'm having trouble making this function, could someone help explain what to do?


int readGoalies(fstream &, Goalie []); // read the goalies from the file into the array


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

    fstream dataFile;
    Goalie goalies[MAX_GOALIES];
    int count;

    if (openFileIn(dataFile, "goalie_stats.csv"))
	{
        // get widget data from file into array
    	count = readGoalies(dataFile, goalies);

    	dataFile.close();




    return 0;
    }
}
Also having some trouble with my sort function, for some reason it can't find my get functions in my class.

This is the error code:
117|error: 'class Goalie' has no member named 'getWins'|
120|error: 'class Goalie' has no member named 'getWins'|
122|error: 'class Goalie' has no member named 'getWins'|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void sortGoaliesByWins(Goalie goalies[], int size)
{
    int maxIndex, maxValue;

   for (int start = 0; start < (size - 1); start++)
   {
      maxIndex = start;
      maxValue = goalies[start].getWins();
      for (int index = start + 1; index < size; index++)
      {
         if (goalies[index].getWins() > maxValue)
         {
            maxValue = goalies[index].getWins();
            maxIndex = index;
         }
      }
      swap(goalies[maxIndex], goalies[start]);
   }
}



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
#ifndef GOALIE_H
#define GOALIE_H

#include<string>

using namespace std;

class Goalie
{
    public:
        // ctors
        Goalie();
        Goalie(const string& n, const string& t);
        Goalie(const string& n, const string& t, int w, int l, int ga, int sa);

        // dtor
         ~Goalie();

         // setters
         void setName(const string& n);
         void setTeam(const string& t);
         void setWins(int w);
         void setLosses(int l);
         void setGoalsAllowed(int ga);
         void setShotsAgainst(int sa);

         // getters
         string getName() const;
         string getTeam() const;
         int getWins() const;
         int getLosses() const;
         int getGoalsAllowed() const;
         int getShotsAgainst()const;
         double getSavePct() const;

    private:

        //attributes
        string name;
        string team;
        int wins {};
        int losses {};
        int goalsAllowed {};
        int shotsAgainst {};
};

#endif // GOALIE_H
You said you recently tried using another header? Perhaps something messed up when you did that. Try cleaning and rebuilding your project. Show the definition of int getWins() const and show how you're #including your header file.

PS: Since all data in your class is either RAII-safe or built-in types, I don't think you need to define a destructor.
Last edited on
Thank you, making a new file with the same stuff seemed to fix that error.


You said you recently tried using another header? Perhaps something messed up when you did that. Try cleaning and rebuilding your project. Show the definition of int getWins() const and show how you're #including your header file.

PS: Since all data in your class is either RAII-safe or built-in types, I don't think you need to define a destructor
I resorted back to what i had before, but with some stuff seeplus helped with, my question is how do make prompt the user to hit 1) to sort by wins , 2) by Losses and 3) by save percentage? I'm getting the file to not fail, but i can't get it to display anything since i'm trying to put it into an array. I want it to prompt the user to pick and option first, then rinse and repeat till they hit zero. I think it needs a do loop for that? I'm just pretty confused

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

    Goalie goalies[MAX_GOALIES];

    fstream myFile("goalie_stats.csv");


	if (!myFile.is_open()) {
		cout << "Cannot open input file\n";
		return 1;
	}







    return 0;
}
I made a menu like this (excluded save percentage), how do i associate the menu with my goalie data?

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
int main()
{

    Goalie goalies[MAX_GOALIES];
    int choice;

    fstream myFile("goalie_stats.csv");


	if (!myFile.is_open()) {
		cout << "Cannot open input file\n";
		return 1;
	}

    do
    {
        std::cout << "0 to quit" << std::endl << "1. Sort by Wins\n";
        std::cout << "2. Sort By Losses\n" << std:: endl;
        std::cin >> choice;

        switch(choice)
        {
        case 0:
            std::cout << "Thanks for using my program!\n";
            return 0;
        case 1:
            std::cout << "Here are the Wins sorted\n" << sortGoaliesByWins << endl;
            break;
        case 2:
            std::cout << "Here are the Losses sorted\n" << sortGoaliesByLosses << endl;
            break;

        }
    }
    while(choice != 0);

    return 0;
}
I made a menu like this (excluded save percentage), how do i associate the menu with my goalie data?

Well, I'd say your getting ahead of yourself. You need to start with reading your input file and storing the information you read into that array.

By the way your instructor's help is not totally accurate:
Your main function will have an array of 100 goalies like this:
Goalie goalies[MAX_GOALIES];

It does not have to be an array of pointers. If you use it as above, then it automatically creates 100 goalie objects, each instantiated using the default "no args" constructor. Therefore when you read the .csv file you will need to use the "setter" functions to set the fields of each goalie.


You don't necessarily need the setter functions to set each field since you have a constructor that sets all the fields you could just use that constructor to "copy" the fields to the array element.

Something like:
 
        goalies[counter] = {name, team, wins, losses, goalsAllowed, shotsAgainst};

Where you read the information into the variables above from the file.

Using arrays rather than vectors and with a menu:

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <iomanip>

class Goalies
{
public:
	// constructors
	Goalies();
	Goalies(const std::string& n, const std::string& t);
	Goalies(const std::string& n, const std::string& t, int w, int l, int ga, int sa);

	// implement setters
	void setName(const std::string& n);
	void setTeam(const std::string& t);
	void setWins(int w);
	void setLosses(int l);
	void setGoalsAllowed(int ga);
	void setShotsAgainst(int sa);

	// implement getters
	std::string getName() const;
	std::string getTeam() const;
	int getWins() const;
	int getLosses() const;
	int getGoalsAllowed() const;
	int getShotsAgainst() const;
	//double getSavePct() const;

private:
	//attributes
	std::string name;
	std::string team;
	int wins {};
	int losses {};
	int goalsAllowed {};
	int shotsAgainst {};
};

Goalies::Goalies() {}
Goalies::Goalies(const std::string& n, const std::string& t) : name(n), team(t) {}
Goalies::Goalies(const std::string& n, const std::string& t, int w, int l, int ga, int sa) : name(n), team(t), wins(w), losses(l), goalsAllowed(ga), shotsAgainst(sa) {}

void Goalies::setName(const std::string& n) { name = n; }
void Goalies::setTeam(const std::string& t) { team = t; }
void Goalies::setWins(int w) { wins = w; }
void Goalies::setLosses(int l) { losses = l; }
void Goalies::setGoalsAllowed(int ga) {	goalsAllowed = ga; }
void Goalies::setShotsAgainst(int sa) {	shotsAgainst = sa; }

std::string Goalies::getName() const { return name; }
std::string Goalies::getTeam() const { return team; }
int Goalies::getWins() const { return wins; }
int Goalies::getLosses() const { return losses; }
int Goalies::getGoalsAllowed() const { return goalsAllowed; }
int Goalies::getShotsAgainst() const { return shotsAgainst; }

void split(const std::string& s, std::string elems[], size_t& noElems, char delim = ',')
{
	const size_t max_elems {noElems};
	noElems = 0;
	const auto pb {[&](size_t st, size_t dp) {elems[noElems++] = s.substr(st, dp - st); }};

	for (auto delimPosition = s.find(delim), tokenStart = 0U; noElems < max_elems && delimPosition != std::string::npos; )
		if (pb(tokenStart, delimPosition); (delimPosition = s.find(delim, (tokenStart = ++delimPosition))) == std::string::npos)
			pb(tokenStart, delimPosition);
}

std::istream& operator>>(std::istream& is, Goalies& g)
{
	if (std::string line; getline(is, line)) {
		constexpr size_t No_Elems {6};
		size_t gotElems {No_Elems};
		std::string tokens[No_Elems] {};

		if (split(line, tokens, gotElems); gotElems == No_Elems) {
			g.setName(tokens[0]);
			g.setTeam(tokens[1]);
			g.setWins(atoi(tokens[2].c_str()));
			g.setLosses(atoi(tokens[3].c_str()));
			g.setGoalsAllowed(atoi(tokens[4].c_str()));
			g.setShotsAgainst(atoi(tokens[5].c_str()));
		}
	}

	return is;
}

std::ostream& operator<<(std::ostream& os, const Goalies& g)
{
	return os << std::left << std::setw(25) << g.getName() << std::setw(15) << g.getTeam() << std::right << std::setw(4) << g.getWins() << std::setw(10) << g.getLosses() << std::setw(15) << g.getGoalsAllowed() << std::setw(15) << g.getShotsAgainst();
}

void showNames(const Goalies goalies[], size_t no_goalies)
{
	std::cout << std::left << std::setw(25) << "Name" << std::setw(15) << "Team" << std::setw(8) << "Wins" << std::setw(8) << "Losses" << std::setw(15) << "Goals Allowed" << std::setw(8) << "Shots Against\n";

	for (size_t g = 0; g < no_goalies; ++g)
		std::cout << goalies[g] << '\n';
}

void sortWins(Goalies goalies[], size_t no_goalies)
{
	std::sort(goalies, goalies + no_goalies, [](auto a, auto b) {return a.getWins() < b.getWins(); });
}

void sortLosses(Goalies goalies[], size_t no_goalies)
{
	std::sort(goalies, goalies + no_goalies, [](auto a, auto b) {return a.getLosses() < b.getLosses(); });
}

int getInt(const std::string& prm)
{
	int i {};

	while ((std::cout << prm) && !(std::cin >> i)) {
		std::cout << "Invalid number\n";
		if (prm.empty()) std::cout << "Please re-enter: ";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	return i;
}

int main()
{
	constexpr size_t Max_Goalies {100};

	std::ifstream myFile("goalie_stats.csv");

	if (!myFile.is_open()) {
		std::cout << "Cannot open input file\n";
		return 1;
	}

	Goalies goalies[Max_Goalies] {};
	size_t no_goalies {};

	for (Goalies g; no_goalies < Max_Goalies && (myFile >> g); goalies[no_goalies++] = g);

	std::cout << "Data read OK. " << no_goalies << " records\n";

	int choice {};

	do
	{
		std::cout << "\n0. to quit\n";
		std::cout << "1. Sort by Wins\n";
		std::cout << "2. Sort By Losses\n";

		switch (choice = getInt("Enter choice: "))
		{
			case 0:
				std::cout << "Thanks for using my program!\n";
				break;

			case 1:
				std::cout << "Here are the Wins sorted\n\n";
				sortWins(goalies, no_goalies);
				showNames(goalies, no_goalies);
				break;

			case 2:
				std::cout << "Here are the Losses sorted\n\n";
				sortLosses(goalies, no_goalies);
				showNames(goalies, no_goalies);
				break;

			default:
				std::cout << "Invalid option\n";
				break;
		}
	} while (choice != 0);
}

Last edited on
|66|error: inconsistent deduction for 'auto': 'long long unsigned int' and then 'unsigned int'|

Does this error mean even though it's the same type, one of the values are just too large?
Last edited on
It means that when assigning multple variables using one auto, the types of the different values being assigned are nor the same.

What's the line causing the error?
I also got 31 errors trying out your main seeplus, can you just help me keep my original file but with my source code:

I suppose i should just discontinue anything else until i get the array with 200 players displayed. So my order is fine i think i just need to insert something where the comment in main is right? Or actually wouldn't it make sense prompting the user to select 1, 2 or 3 then displaying the array in the proper sorted format?

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
int main()
{

    Goalie goalies[MAX_GOALIES];
    int choice;
    int count;

    fstream myFile("goalie_stats.csv");


	if (!myFile.is_open()) {
		cout << "Cannot open input file\n";
		return 1;
	}

	// file is open, so display the array.



    do
    {
        std::cout << "0 to quit" << std::endl << "1. Sort by Wins\n";
        std::cout << "2. Sort By Losses\n" << std:: endl;
        std::cin >> choice;

        switch(choice)
        {
        case 0:
            std::cout << "Thanks for using my program!\n";
            return 0;
        case 1:
            std::cout << "Here are the Wins sorted\n" << sortGoaliesByWins << endl;
            break;
        case 2:
            std::cout << "Here are the Losses sorted\n" << sortGoaliesByLosses << endl;
            break;

        }
    }
    while(choice != 0);

    return 0;
}
Last edited on
I also got 31 errors trying out your main seeplus


It compiles and runs OK as C++17 with VS2019...
line 66 on ur code, since my file has to be run in 3 headers, yours is giving me way to many errors, and i tried separating those headers since i see urs is still basically separated by .h and .cpp, but still got 30+ errors


It means that when assigning multple variables using one auto, the types of the different values being assigned are nor the same.

What's the line causing the error?
Last edited on
Mines 2017 too, but i tried using ur code with 3 headers total and got all the errors, i did make a separate test file to run it your exact way and only got the line 66 error


It compiles and runs OK as C++17 with VS2019..
66|error: inconsistent deduction for 'auto': 'long long unsigned int' and then 'unsigned int'|


OK. The issue is with this line of code

 
for (auto delimPosition = s.find(delim), tokenStart = 0U; noElems < max_elems && delimPosition != std::string::npos; )


as the type of size_t (the type of the return value from .find() changes between 32 and 64 bit compiles. Hence the type of initial value for tokenStart needs to match the required type. So

 
for (auto delimPosition = s.find(delim), tokenStart = decltype(s.find(delim))(0); noElems < max_elems && delimPosition != std::string::npos; )


This then compiles/runbs ok as C++17 for 32 bit and 64 bit compiles with VS2019.

If you're getting further errors, are you compiling as C++17? What compiler are you using and have you set/using the option to compile as C++17?

Or alternatively (which some will prefer.....):

1
2
3
4
5
6
7
8
9
10
11
12
void split(const std::string& s, std::string elems[], size_t& noElems, char delim = ',')
{
	const size_t max_elems {noElems};
	noElems = 0;
	const auto pb {[&](size_t st, size_t dp) {elems[noElems++] = s.substr(st, dp - st); }};

	size_t tokenStart {};

	for (auto delimPosition = s.find(delim); noElems < max_elems && delimPosition != std::string::npos; )
		if (pb(tokenStart, delimPosition); (delimPosition = s.find(delim, (tokenStart = ++delimPosition))) == std::string::npos)
			pb(tokenStart, delimPosition);
}

Last edited on
Pages: 123