私は昨日から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)型の変数に変換します。」
私の印象は、関数は文字列の不可欠な部分を取り、それを入力として使うということでした。
(私はここで質問する方法を正確に知りません。私はプログラミングにも不慣れです)ありがとう。
文字列と他の数値型との間の変換に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デバイスのように文字列を操作するにするのに便利な方法です。
参考までに、クラス間の継承関係は次のとおりです。
質問に答えます。 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の誰かからそれを盗んで洗練しましたが、私は最初の作者には言及していません。
からC++入門:
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()
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にゼロを残しました、そして我々は皆、何回ゼロが何をもたらすのか知っています。
2回目にint値を入力しただけでは、すべて期待通りに動作しました。
あなたのコードが失敗する原因となったのは偽のRSでした。