问题
So i'm trying to do something like this:
input:
hi my name is clara
expected output:
hi, my, name, is, clara
My program looks like this:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string str;
getline(cin, str);
istringstream ss(str);
do {
string word;
ss >> word;
cout << word << ", ";
}
while (ss);
}
But the output looks like this
hi, my, name, is, clara, ,
Can someone help me fix this?
回答1:
This should fix it:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string str;
getline(cin, str);
string word;
istringstream ss(str);
bool firstIteration = true;
while(ss >> word) {
if(!firstIteration) {
cout << ", ";
}
cout << word;
firstIteration = false;
};
}
Check the working demo here please.
I am using this idiom (pattern?) in many programming languages, and all kind of tasks where you need to construct delimited output from list like inputs. Let me give the abstract in pseudo code:
empty output
firstIteration = true
foreach item in list
if firstIteration
add delimiter to output
add item to output
firstIteration = false
In some cases one could even omit the firstIteration
indicator variable completely:
empty output
foreach item in list
if not is_empty(output)
add delimiter to output
add item to output
回答2:
If you like a solution without a if-clause each time the while loops executes.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string str;
getline(cin, str);
string word;
istringstream ss(str);
string delimiter = "";
while(ss >> word) {
cout << delimiter << word;
delimiter = ", ";
};
}
回答3:
You are not handling the case when operator>>
fails to read a word once the end of the istringstream
has been reached, thus leaving your word
variable empty. You are outputting the word
before checking if the read was actually successful. That is why you end up with a blank word at the end of your output. You would need to check for that condition, eg:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string str;
getline(cin, str);
istringstream ss(str);
do {
string word;
if (!(ss >> word)) break;
cout << word << ", ";
}
while (true);
}
Alternatively:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string str;
getline(cin, str);
istringstream ss(str);
string word;
while (ss >> word)
{
cout << word << ", ";
}
}
However, either approach would still leave you with a trailing comma at the end of the last word.
You could use a variable to control when the comma is output, eg:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string str;
getline(cin, str);
istringstream ss(str);
string word;
bool first = true;
while (ss >> word)
{
if (first)
first = false;
else
cout << ", ";
cout << word;
}
}
But, in this situation, it would be cleaner to simply output the first word by itself, and then enter a loop to output the remaining words prefixed by a comma, eg:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
string str;
getline(cin, str);
istringstream ss(str);
string word;
if (ss >> word)
{
cout << word;
while (ss >> word)
{
cout << ", " << word;
}
}
}
来源:https://stackoverflow.com/questions/63796088/how-to-build-a-comma-delimited-list-from-strings-w-o-the-extra-delimiter-at-the