Что именно делает stringstream?

Со вчерашнего дня я пытаюсь выучить C ++ и использую этот документ:http://www.cplusplus.com/files/tutorial.pdf (стр. 32). Я нашел код в документе и запустил его. Я попытался ввести Rs 5,5 для цены и целое число для количества, и результат был 0.
Я попытался ввести 5,5 и 6, и вывод был правильным.

// stringstreams
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main ()
{
string mystr;
float price = 0;
int quantity = 0;

cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
return 0;
}

Вопрос: Что именно делает команда mystring? Цитата из документа:

«В этом примере мы получаем числовые значения из стандартного ввода
косвенно. Вместо того, чтобы извлекать числовые значения непосредственно из
стандартный ввод, мы получаем строки из стандартного ввода (CIN) в
строковый объект (mystr), а затем мы извлекаем целочисленные значения из
эту строку в переменную типа int (количество). «

У меня сложилось впечатление, что функция будет принимать неотъемлемую часть строки и использовать ее в качестве входных данных.

(Я точно не знаю, как задать вопрос здесь. Я также новичок в программировании)
Спасибо.

80

Решение

Иногда очень удобно использовать поток строк для преобразования между строками и другими числовыми типами. Использование stringstream похоже на использование iostreamтак что не бремя учиться.

Строковые потоки могут использоваться как для чтения строк, так и для записи данных в строки. Он в основном работает со строковым буфером, но без реального канала ввода-вывода.

Основные функции-члены класса stringstream:

  • str(), который возвращает содержимое своего буфера в виде строки.

  • str(string), который устанавливает содержимое буфера в строковый аргумент.

Вот пример того, как использовать строковые потоки.

ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;

Результат dec: 15 hex: f,

istringstream более или менее того же использования.

Подводя итог, струнный поток является удобным способом манипулировать строками как независимое устройство ввода / вывода.

К вашему сведению, отношения наследования между классами:

классы потока строк

137

Другие решения

Ответить на вопрос. stringstream в основном позволяет лечить string объект как streamи использовать все stream функции и операторы на нем.

Я видел, что он используется в основном для форматированного вывода / ввода совершенства.

Один хороший пример будет c++ реализация преобразования номера в потоковый объект.

Возможный пример:

template <class T>
string num2str(const T& num, unsigned int prec = 12) {
string ret;
stringstream ss;
ios_base::fmtflags ff = ss.flags();
ff |= ios_base::floatfield;
ff |= ios_base::fixed;
ss.flags(ff);
ss.precision(prec);
ss << num;
ret = ss.str();
return ret;
};

Может быть, это немного сложно, но это довольно сложно. Вы создаете stringstream объект ss, измените его флаги, введите число с operator<<и извлечь его через str(), я думаю что operator>> может быть использован.

Также в этом примере string буфер скрыт и не используется явно. Но было бы слишком долго писать о каждом возможном аспекте и сценарии использования.

Примечание: я, вероятно, украл его у кого-то на SO и уточнил, но у меня нет оригинального автора.

16

От C ++ Primer:

istringstream тип читает строка, ostringstream пишет строка, а также stringstream читает и пишет строка.

Я сталкиваюсь с некоторыми случаями, когда это удобно и кратко использовать stringstream.

Случай 1

Это из одно из решений за эта проблема Leetcode. Это демонстрирует очень подходящий случай, когда использование stringstream является эффективным и кратким.

предполагать a а также b комплексные числа, выраженные в строковом формате, мы хотим получить результат умножения a а также b также в строковом формате. Код выглядит следующим образом:

string a = "1+2i", b = "1+3i";
istringstream sa(a), sb(b);
ostringstream out;

int ra, ia, rb, ib;
char buff;
// only read integer values to get the real and imaginary part of
// of the original complex number
sa >> ra >> buff >> ia >> buff;
sb >> rb >> buff >> ib >> buff;

out << ra*rb-ia*ib << '+' << ra*ib+ia*rb << 'i';

// final result in string format
string result = out.str()

случай 2

Это также из проблема кода что требует от вас упростить заданную строку пути, одно из решений с использованием stringstream самое элегантное, что я видел:

string simplifyPath(string path) {
string res, tmp;
vector<string> stk;
stringstream ss(path);
while(getline(ss,tmp,'/')) {
if (tmp == "" or tmp == ".") continue;
if (tmp == ".." and !stk.empty()) stk.pop_back();
else if (tmp != "..") stk.push_back(tmp);
}
for(auto str : stk) res += "/"+str;
return res.empty() ? "/" : res;
}

Без использования stringstream было бы сложно написать такой лаконичный код.

12

Вы ввели буквенно-цифровой и int, пробел с разделителями в mystr,

Затем вы попытались преобразовать первый токен (с разделителем-пробелом) в int,

Первым токеном был RS, который не удалось преобразовать в intоставляя ноль для myprice, и мы все знаем, что ноль раз что-либо дает.

Когда вы только ввели значения int во второй раз, все работало так, как вы ожидали.

Это была ложная RS, которая вызвала сбой вашего кода.

2
По вопросам рекламы [email protected]