05. Invalid Input
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
string input;
getline(cin, input);
istringstream iss;
vector<int> numbers;
int total = 0;
int number;
iss >> input;
while(iss >> number)
{
total += number;
numbers.push_back(number);
}
cout << total;
return 0;
}
Нещо забих на тази задача. Исках да извадя сбора на числата и след това да се опитам да принтирам остатъка от стриима, но не влиза дори в while цикъла.
Благодаря зя отговора. Логиката ме обърка. Не се сещах как да ги извадя едно от друго числата и стринговете.
Здравейте!
Аз също забих с това, как да оставя само думите в стринга и след 500 различни опита, все пак използвах показания в този пост начин.
Всичко работи супер, но не разбирам защо точно този момент конкретно работи по този начин:
Потокът се записва в string и след това проверяваме дали всеки елемент от този string е буква или не. Ако е буква - се записва във втори string, който после се принтира. Как обаче се разграничава че потокът се състои от отделни думи и програмата знае кога да сложи white space, след като ги въртим елемент по елемент от string-а? Не трябва ли така както е записано,да слага white space след всяка отделна буква, която засече?
Слагам цялото решение, в случай че не става ясно какво точно питам (то и аз не съм сигурна вече );
http://pastebin.com/PMfeCjdk
Благодаря предварително! :)
Кремена
Един съвет от мен - ако се опитваш да четеш чужд код и не успяваш да схванеш логиката му сложи си един брейкпойнт на подходящо място (обикновено там където имаш цикъл от някакъв тип или пък четеш/подаваш нещо) и върви стъпка по стъпка, за да го видиш какво прави като задължително следиш промените на променливите, за да си обясниш какво всъщност прави това парче от кода, на което си в момента.
За конкратния случай - когато ползваш потоци които ще подавш към някаква променлива е важен от какъв тип ще е променливата, за да можеш да извлечеш съответния тип. В случая това е стринг. Стандартния delimiter е space. Тоест извличането става дума по дума, а не символ по символ.
int main() {
std::string input;
getline(std::cin, input);
titleCase(input);
return 0;
}
std::istringstream lineStrm(line);
std::string words;
std::string printWord;
while(lineStrm >> words){ --> тук казваш - докато потока може да се излива в стринга words, върти цикъла. Какво се случва - докато от потока успява да чете стрингове ги взима и записва цялата дължина на стринга (цялата дума) докато не срещне space.
if(isalpha(words[0])){ --> ако горното условие е вярно значи сме срещнали стринг и тук проверява не символ по символ, а дали първият символ е буква
printWord += words + " "; --> в случай, че предходната проверка е вярна, към стринга printWords добави стринга който от потока се е записал в стринга words, след което добавя space.
}
}
След първата итерация на цикъла, while(lineStrm >> words), сме извлякли първата дума и следва второ завъртане на цикъла. Ако отново срещне стринг, прави проверките, и следва трето завъртане на цикъла. Ако срещне нещо различно от стринг ще излезе от цикъла и продължава с изпълнението на останалия код от програмата.
Или накратко казано, нещата които са те объркали в случая са, че когато поток се записва в стринг, то той записва цялата дължина на стринга до срещане делимитер-а който е space. И второто нещо, е че не си обърнала внимание на if проверката, която не проверява символ по символ, а само първия, след което, ако проверката е вярна, към стринга printWord добавя извлечения стринг и след него слага спейс. Логиката в това е, че е достатъчно само първия елемент от стринга да е буква, за да кажем, че това е стринг, защото знаем, че ако е цифра, то стрийма не би го подал към стринга.
Ето ти и моето решение, да го разгледаш. Доста е сходно, проверките ми са малко по-различни, но е базирано на същата логика:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
void titleCase(std::string input) {
std::istringstream iss(input);
std::string temp;
int found = 0;
std::vector<int> numbers;
std::vector<std::string> issText;
while (!iss.eof()) {
iss >> temp;
if(std::istringstream(temp) >> found) {
numbers.push_back(found);
} else {
issText.push_back(temp);
}
}
int numbersSize = numbers.size();
int issTextSize = issText.size();
int sum = 0;
for (int i = 0; i < numbersSize; ++i) {
sum += numbers[i];
}
std::cout << sum << std::endl;
for (int i = 0; i < issTextSize; ++i) {
std::cout << issText[i] << " ";
}
}
int main() {
std::string input;
getline(std::cin, input);
titleCase(input);
return 0;
}
Много благодаря за съвета и за подробния отговор! :)
Определено си прав, за записването на потока в стринг имах предположение че става нещо такова, но абсолютно бях пропуснала момента, че проверява само първия символ от конкретния стринг! Което в случая работи добре за задачата, но като цяло е сериозен пропуск.
Включвам се отново, за да се самокорегирам :) Там където казвам "...достатъчно само първия елемент от стринга да е буква, за да кажем, че това е стринг, защото знаем, че ако е цифра, то стрийма не би го подал към стринга.", не съм съвсем прав. Ако имаме например 6fun стрийма няюа да извлече само fun, ами 6fun защото 6 е част от стринга. В такъв случай проверката if(isalpha(word[0])) ще фейлне защото първия символ от стринга не е буква. За конкретната задача (доколкото помня условието) това не е проблем, защото цифрите са отделени от стринга. Но ако не бяха, това щеше да е проблем и да се изисква по-различен подход от сорта на този, който е необходим в задачата signal and the noise.