Что именно делает 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) в a строковый объект (mystr), а затем мы извлекаем целочисленные значения из эта строка в переменную типа int (quantity)."

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

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

4 77
c++

4 ответа:

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

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

основными функциями-членами класса stringstream являются

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

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

вот пример использования строковых потоков.

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

результат dec: 15 hex: f.

istringstream имеет более или менее одинаковое использование.

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

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

string stream classes

чтобы ответить на вопрос. 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 буфера скрыт и не используется явно. Но это было бы слишком долго поста, чтобы писать о каждом возможном аспекте и прецеденте.

примечание: Я, вероятно, украл его у кого-то на так и изысканный, но у меня нет оригинального автора отметил.

С C++ Primer:

The istringstream тип читает a строка,ostringstream пишет a строка и 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

это тоже от проблема с leetcode что требуется упростить заданную строку пути,одно из решений с использованием 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 было бы трудно написать такой краткий код.

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

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

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

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

Это был поддельный RS, который вызвал ваш код неудача.