Как построить список с разделителями-запятыми из строк без дополнительного разделителя в конце?
Итак, я пытаюсь сделать что-то вроде этого:
ввод:
hi my name is clara
ожидаемый результат:
hi, my, name, is, clara
Моя программа выглядит так:
#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);
}
Но результат выглядит так
hi, my, name, is, clara, ,
Может кто-нибудь помочь мне это исправить?
3 ответа
Это должно исправить это:
#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;
};
}
Проверьте рабочую демо - версию здесь пожалуйста.
Я использую эту идиому (шаблон?) Во многих языках программирования и во всех видах задач, в которых вам нужно создать вывод с разделителями из списка, например входы. Приведу аннотацию в псевдокоде:
empty output
firstIteration = true
foreach item in list
if firstIteration
add delimiter to output
add item to output
firstIteration = false
В некоторых случаях можно даже опустить
firstIteration
индикаторная переменная полностью:
empty output
foreach item in list
if not is_empty(output)
add delimiter to output
add item to output
Вы не ведете дела, когда
operator>>
не может прочитать ни слова после окончания
istringstream
был достигнут, таким образом оставив ваш
word
переменная пуста. Вы выводите
word
перед проверкой, было ли чтение действительно успешным. Вот почему вы получаете пустое слово в конце вывода. Вам нужно будет проверить это условие, например:
#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);
}
Альтернативно:
#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 << ", ";
}
}
Однако любой подход все равно оставит вам запятую в конце последнего слова.
Вы могли бы использовать переменную для управления, когда запятая выводится, например:
#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;
}
}
Но в этой ситуации было бы проще просто вывести первое слово само по себе, а затем войти в цикл для вывода оставшихся слов с префиксом запятой, например:
#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;
}
}
}
Если вам нравится решение без предложения if каждый раз, когда выполняется цикл while.
#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 = ", ";
};
}