web-dev-qa-db-ja.com

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(Quantity)型の変数に変換します。」

私の印象は、関数は文字列の不可欠な部分を取り、それを入力として使うということでした。

(私はここで質問する方法を正確に知りません。私はプログラミングにも不慣れです)ありがとう。

88
user3104350

文字列と他の数値型との間の変換にstringstreamを使用すると便利なことがあります。 stringstreamの使用法はiostreamの使用法と似ているため、習得するのに負担はありません。

文字列ストリームは、文字列の読み取りと文字列へのデータの書き込みの両方に使用できます。これは主に文字列バッファで機能しますが、実際のI/Oチャネルはありません。

Stringstreamクラスの基本的なメンバー関数は次のとおりです。

  • バッファの内容を文字列型で返すstr()

  • str(string)は、バッファの内容を文字列引数に設定します。

これは文字列ストリームの使い方の例です。

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

結果はdec: 15 hex: fです。

istringstreamは、ほぼ同じ用法です。

まとめると、stringstreamは独立したI/Oデバイスのように文字列を操作するにするのに便利な方法です。

参考までに、クラス間の継承関係は次のとおりです。

string stream classes

151
richard.g

質問に答えます。 stringstreamでは、基本的にstringオブジェクトをstreamのように扱い、すべてのstreamの関数とその演算子を使用できます。

私はそれがフォーマットされた出力/入力の良さのために主に使われるのを見ました。

1つの良い例は、numberをストリームオブジェクトに変換する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の誰かからそれを盗んで洗練しましたが、私は最初の作者には言及していません。

18
luk32

からC++入門

istringstream型は文字列を読み取り、ostringstream文字列を書き込みます。stringstream文字列を読み書きします

stringstreamを使うのが便利で簡潔な場合がいくつかあります。

ケース1

それは 解決策の1つこのleetcodeの問題 からです。これは、stringstreamの使用が効率的かつ簡潔であるという非常に適切なケースを示しています。

abが文字列形式で表現された複素数であると仮定すると、abの乗算の結果も文字列形式で取得する必要があります。コードは次のとおりです。

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を使わなければ、そのような簡潔なコードを書くのは難しいでしょう。

16
jdhao

英数字とintを入力しました。空欄はmystrで区切ります。

次に、最初のトークン(空白区切り)をintに変換しようとしました。

最初のトークンはRSで、これはintへの変換に失敗し、mypriceにゼロを残しました、そして我々は皆、何回ゼロが何をもたらすのか知っています。

2回目にint値を入力しただけでは、すべて期待通りに動作しました。

あなたのコードが失敗する原因となったのは偽のRSでした。

2
ilocos joe