I would like to check the following:
- If the last character appended to the
stringstream
is a comma. - If it is remove it.
std::stringstream str; str << "[" //loop which adds several strings separated by commas str.seekp(-1, str.cur); // this is to remove the last comma before closing bracket str<< "]";
The problem is if nothing is added in the loop, the opening bracket is removed from the string. So I need a way to check whether the last character is a comma. I did that like this:
if (str.str().substr(str.str().length() - 1) == ",") { str.seekp(-1, rteStr.cur); }
But I don't feel very good about this. Is there a better way to do this?
About the loop:
Loop is used to tokenize a set of commands received through sockets and format it to send to another program through another socket. Each command ends with an OVER
flag.
std::regex tok_pat("[^\\[\\\",\\]]+"); std::sregex_token_iterator tok_it(command.begin(), command.end(), tok_pat); std::sregex_token_iterator tok_end; std::string baseStr = tok_end == ++tok_it ? "" : std::string(*tok_it); while (baseStr == "OVER") { //extract command parameters str << "extracted_parameters" << "," }
The way I often deal with these loops where you want to put something like a space or a comma between a list of items is like this:
int main() { // initially the separator is empty auto sep = ""; for(int i = 0; i < 5; ++i) { std::cout << sep << i; sep = ", "; // make the separator a comma after first item } }
Output:
0, 1, 2, 3, 4
If you want to make it more speed efficient you can output the first item using an if()
before entering the loop to output the rest of the items like this:
int main() { int n; std::cin >> n; int i = 0; if(i < n) // check for no output std::cout << i; for(++i; i < n; ++i) // rest of the output (if any) std::cout << ", " << i; // separate these }
In your situation the first solution could work like this:
std::regex tok_pat("[^\\[\\\",\\]]+"); std::sregex_token_iterator tok_it(command.begin(), command.end(), tok_pat); std::sregex_token_iterator tok_end; std::string baseStr = tok_end == ++tok_it ? "" : std::string(*tok_it); auto sep = ""; // empty separator for first item while (baseStr == "OVER") { //extract command parameters str << sep << "extracted_parameters"; sep = ","; // make it a comma after first item }
And the second (possibly more time efficient) solution:
std::regex tok_pat("[^\\[\\\",\\]]+"); std::sregex_token_iterator tok_it(command.begin(), command.end(), tok_pat); std::sregex_token_iterator tok_end; std::string baseStr = tok_end == ++tok_it ? "" : std::string(*tok_it); if (baseStr