[解決済み] iomanipのマニピュレーターで「粘着性」があるのはどれ?
質問
最近
stringstream
を作成する際に、私が間違って
std::setw()
は挿入のたびに文字列ストリームに影響を与えると、私が明示的に変更するまで、間違って想定していたためです。しかし、挿入の後は常にアンセットされます。
// With timestruct with value of 'Oct 7 9:04 AM'
std::stringstream ss;
ss.fill('0'); ss.setf(ios::right, ios::adjustfield);
ss << setw(2) << timestruct.tm_mday;
ss << timestruct.tm_hour;
ss << timestruct.tm_min;
std::string filingTime = ss.str(); // BAD: '0794'
では、いくつか質問をさせていただきます。
-
なぜ
setw()
はこのようになりますか? - 他のマニピュレーターもこのような感じなのでしょうか?
-
との間に動作の違いはあるのでしょうか?
std::ios_base::width()
とstd::setw()
? - 最後に、この動作を明確に文書化したオンライン リファレンスはありますか。私のベンダーのドキュメント (MS Visual Studio 2005) では、これを明確に示していないようです。
どのように解決するのですか?
以下のコメントからの重要な注意事項。
マーティンによる
<ブロッククオート@Charelesです。では、この条件ではすべてのマニピュレータがスティッキーになりますね。ただし、setwは使用後にリセットされるようです。
チャールズによって。
<ブロッククオートその通り!そして、setwが異なる振る舞いをするように見える唯一の理由は、フォーマットされた出力操作に、出力ストリームを明示的に .width(0) にする要件があるためです。
以下は、上記の結論に至った議論です。
コードを見ると、以下のマニピュレータは、ストリームではなくオブジェクトを返しています。
setiosflags
resetiosflags
setbase
setfill
setprecision
setw
これは、ストリームに適用された次のオブジェクトにのみ操作を適用する一般的なテクニックです。残念ながら、これはスティッキーであることを排除するものではありません。テストによると
setw
はスティッキーであることを示しています。
setiosflags: Sticky
resetiosflags:Sticky
setbase: Sticky
setfill: Sticky
setprecision: Sticky
他のすべてのマニピュレータは、ストリーム・オブジェクトを返す。したがって、これらのマニピュレータが変更した状態情報は、ストリーム・オブジェクトに記録されなければならず、したがって(他のマニピュレータが状態を変更するまで)永久的である。従って、以下のマニピュレータは スティッキー マニピュレータでなければならない。
[no]boolalpha
[no]showbase
[no]showpoint
[no]showpos
[no]skipws
[no]unitbuf
[no]uppercase
dec/ hex/ oct
fixed/ scientific
internal/ left/ right
これらのマニピュレータは、実際にはストリームオブジェクトではなく、ストリームそのものに対して操作を行います(技術的には、ストリームはストリームオブジェクトの状態の一部ですが)。しかし、私は、それらがストリームオブジェクトの状態の他の部分に影響を与えるとは思いません。
ws/ endl/ ends/ flush
結論としては、私のバージョンでは setw が唯一スティッキーでないマニピュレータのようです。
Charles の場合、チェーン内の次のアイテムにのみ影響を与える簡単なトリックです。
オブジェクトを使用して一時的に状態を変更し、その後オブジェクトを使用して元の状態に戻す方法の例です。
#include <iostream>
#include <iomanip>
// Private object constructed by the format object PutSquareBracket
struct SquareBracktAroundNextItem
{
SquareBracktAroundNextItem(std::ostream& str)
:m_str(str)
{}
std::ostream& m_str;
};
// New Format Object
struct PutSquareBracket
{};
// Format object passed to stream.
// All it does is return an object that can maintain state away from the
// stream object (so that it is not STICKY)
SquareBracktAroundNextItem operator<<(std::ostream& str,PutSquareBracket const& data)
{
return SquareBracktAroundNextItem(str);
}
// The Non Sticky formatting.
// Here we temporariy set formating to fixed with a precision of 10.
// After the next value is printed we return the stream to the original state
// Then return the stream for normal processing.
template<typename T>
std::ostream& operator<<(SquareBracktAroundNextItem const& bracket,T const& data)
{
std::ios_base::fmtflags flags = bracket.m_str.flags();
std::streamsize currentPrecision = bracket.m_str.precision();
bracket.m_str << '[' << std::fixed << std::setprecision(10) << data << std::setprecision(currentPrecision) << ']';
bracket.m_str.flags(flags);
return bracket.m_str;
}
int main()
{
std::cout << 5.34 << "\n" // Before
<< PutSquareBracket() << 5.34 << "\n" // Temp change settings.
<< 5.34 << "\n"; // After
}
> ./a.out
5.34
[5.3400000000]
5.34
関連
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] C++のPOD型とは何ですか?
-
[解決済み] C++の識別子でアンダースコアを使用する場合のルールについて教えてください。
-
[解決済み] C++のファンクターとその使い方とは?
-
[解決済み】C++17の新機能は何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】識別子 "string "は未定義?
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】変数やフィールドがvoid宣言されている
-
[解決済み】なぜ、constでない参照は一時的なオブジェクトにバインドできないのでしょうか?