• 締切済み

C++のstringstreamについて

こんにちは。 C++のstringstreamについて教えてください。 stringstreamはbasic_stringstream<char, char_traits<char>,allocator<char> >がtypedefされたもので、他にbasic_stringstream<wchar_t, char_traits<wchar_t>,allocator<wchar_t> >というwstringstreamというものも存在していますよね。 同じtemplateクラスに異なるパラメータを渡しているというのはわかるのですが、stringstreamとwstringstreamでは内部実装は異なるものだと思っています。 たとえばwchar_tの場合、文字列に数字などを入れる場合、swprintfという関数を使用しますよね。 同様にcharの場合は、文字列に数字などを入れる場合、sprintfという関数を使用することになるかと思います。 basic_stringstreamクラスはこの関数の切り分けはどのように実現させているのでしょうか? 私は関数のオーバーロード(sprintfとswprintfを同じ名前でラップ)か、クラスの特殊化程度しか思いつきませんでした。 char_traitsが魔法の種のような気がするのですがいまいちよくわかりません。 よろしければご教授願います。 /* 開発環境はVisualStudio2008 academic editionです。 */

  • 0xEF
  • お礼率59% (193/327)

みんなの回答

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.1

swprintfやsprintfはCの関数でしょう。C++のクラスを作成するのにCの関数を使うという仮定はいかがなものでしょうか。 まあ基本的にbasic_stringstreamは共通で、charとwchar_tで変える必要がある部分はchar_traitsのメソッドを特殊化することで対応できると思いますけど。

関連するQ&A

  • C++について

    C++の独学初心者です 仕様書?やエラーの見方が全くわかりません 例えば vscodeにてreverse()の関数の説明を見ると以下のような仕様書というのでしょうか?ものが見れますが 私はここからわかるのは返り値がvoidであるということぐらいがだいたい想像できるだけです これはどの様に見れば良いのでしょうか? 解説している様なサイトがあれば教えてください void std::__1::reverse<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::iterator>(std::__1::__wrap_iter<...> __first, std::__1::__wrap_iter<...> __last) よろしくお願いします

  • explicitの定義は?

    C++においてexplicitについて調べると explicit <エクスプリシット>  「明示的」  引数をひとつだけ受け取るコンストラクタに付けることのできる C++ 言語のキーワード。  クラスを関数の引数として使う場合、その関数には、クラスのコンストラクタの引数になっているものも渡すことができてしまう。これは暗黙的にコンストラクタが呼び出されるからである。このとき、「コンストラクタの引数」がまるで「関数の引数」であるかのように振る舞ってしまい、本来ならコンパイルエラーとなって欲しい場面でも、見えない部分でコンストラクタが呼ばれることでコンパイルが通ってしまう。その結果、想定していない動作をする可能性がある。  そこで、コンストラクタには「暗示的に呼び出せない」ようにするためのキーワードがある。それが explicit である。このキーワードを付けたコンストラクタは、必ず明示的に呼び出される必要があり、前述のようなことをしようとするとコンパイル時にエラーが発生する。 となっていました 「クラスを関数の引数として使う場合、その関数には、クラスのコンストラクタの引数になっているものも渡すことができてしまう。」 のところが分かりません 具体例で説明してください 例えば template<class CharType,class Attr=char_traits<CharType>, Class Allocator=allocator<T> >class basic_string クラスのコンストラクタが explicit basic_string(const Allocator &a=Allocator()); ですがこのケースについて説明していただければ幸いです

  • c言語 int型の数字をchar型の配列に

    c言語についてです。 int型の数字をchar型の配列に入れたいです。 関数に対してint型の数字を文字列として渡し、 関数内でchar型の配列に格納したいです。 例として、 a(char a[]){  ~~  ~~ } int main(void){ int x = 5678;  ~~  a(x); } とできるようにしたいです。 しかしこれだと5678という値がそのままchar型の一つの配列に入る?ため正しくないです。 欲しい結果としてはちゃんとa関数内で、 a[1] = '5' a[2] = '6' a[3] = '7' a[4] = '8' となってほしいです。 もともと渡す値が”5678”となっていれば結果は正しく出るのですが、 渡す値がint型と決まっているためどうにかして5678を”5678”とすればいいのではないかと考えています。 つまり5678を単純に文字列に変換すればいいのでしょうか? またプログラム内ではsprintfやatolを使用しないで実現させたいです。 難しいかもしれませんがお願いします。 なんだか説明が下手ですみません。 お願いいたします。

  • 関数のパラメタ(C++)

    HRESULT AddFile( LPCWSTR pRemoteName, LPCWSTR pLocalName ); というメソッドがあり、 「LPCWSTR」はmapidefs.hの中で typedef const WCHAR FAR * LPCWSTR; と定義されています。 この関数を AddFile(L"http://172.0.0.1/index.htm","c:\\tmp\\index.htm"); ※\\は正しい。 のように呼ぶ場合は成功するのですが、 パラメタの値をいったん格納した変数を参照するように変更したい場合、 どのように書けばよいでしょうか。 文字列のポインタを引数にとる関数であれば、 aaa("zzz"); あるいは char str[256]="zzz"; aaa(str); のように書けばよいことはわかっていますが 同じ要領でやろうとするとこの場合エラーになってしまいます。

  • C++で>>演算子のオーバーロード

    C++学習者です。 Visual Studio Community 上で、ある教本を使って勉強しています。 現在Stringというクラスを作って、文字列に対して連結や部分文字列の取り出しなどができるようにするための色々な演算子のオーバーロードをする関数を定義していますが、疑問点がありますので、お聞きしたいと思います。 Stringクラスのプライベート変数は、文字列の長さを表すlength と、new 演算子で動的に確保するメモリー領域の始まりのアドレスを表す *sPtr の二つです。 クラス内ではパブリックなメンバー関数としていろいろな演算子がオーバーロードされていて、これらについてはよく理解できるのですが、friend 関数として定義されている入力演算子(>>)について納得がいかない部分があります。 その関数は次のようになっています。 istream &operator>>(istream &input, String &s) { char temp[100]; input >> setw(100) >> temp; s = temp; return input; } わからないのは s = temp; の部分です。 sはStringクラスのオブジェクトで、temp は単なる文字列なのに、なぜ代入できるのでしょうか? 代入演算子=のオーバーロード関数も下に挙げますが、この中でも単なる文字列をStringクラスのオブジェクトに代入できるようにはなってないように見えます。 const String &String::operator=(const String &right) { if (&right != this){ // avoid assignment of itself delete [ ] sPtr; length = right.length; sPtr = new char[ length + 1]; strcpy(sPtr, right.sPtr); } else cout<< "attempted to assign a String to itself \n\n"; return *this; } どなたか答えて頂けると有難いです。

  • テンプレートが複雑すぎる?

    以下のような文字列比較関数を作ろうと思っています。 ○配列変数であるときは配列版を、そうでないときはポインタ版を呼び出す  配列のサイズがわかるときは、仮に\0で終端していなくてもそれ以上検索しない ○charかwchar_tかを意識せずに使える ○charとwchar_tという記述ではなく、templateでできるだけジェネリック?的に記述したい //charを入れるとwchar_t、wchar_tを入れるとcharを返すメタ関数 template<typename T> struct invert{}; template<> struct invert<char>{ typedef wchar_t t; }; template<> struct invert<wchar_t>{ typedef char t; }; //同じ型同士の比較は省略 //A: 両方ポインタ template<typename T> bool compare(const T *const &v1, const typename invert<T>::t *const &v2); //B1: 左がポインタ、右が配列 template<typename T, size_t L> bool compare(const T *const &v1, const typename invert<T>::t (&v2)[L]); //B2: Tとtypename invert<T>::tを逆に template<typename T, size_t L> bool compare(const typename invert<T>::t *const &v1, const T (&v2)[L]); //C: 左が配列、右がポインタ //省略 //D: 両方配列 template<typename T, size_t L1, size_t L2> bool compare(const T (&v1)[L1], const typename invert<T>::t (&v2)[L2]); char aa[] = "abc"; char *pa = aa; wchar_t aw[] = L"abc"; wchar_t *pw = aw; bool c1 = compare(pa, pw); //A bool c2 = compare(pa, aw); //B1はC2784, B2なら可 bool c3 = compare(aa, pw); //C bool c4 = compare(aa, aw); //DはC2784 invert<T>::t (&v2)[L]という記述が複雑?なのかB1は呼べず、B2と記述すると通りました。 しかしDはどちらも配列であるため、B2のように回避できません。 オーバーロードを全て記述せずに、できるだけ簡単にすます方法はありませんか? 環境はVC++2010です。

  • UNICODE対応ってどういうことなのかわかりません

    VC++とかでUNICODE対応というと文字列をwchar_t型で扱うことなのかなと思うのですが、その場合UTF-8ってどういう扱いになっているのでしょうか? ウィキペディアを見ると、インターネットではUTF-8が主流であるようなことが書かれています。 UTF-8はアスキー文字セットとも互換性があるようなので、char型で文字列を扱うのかなと思いました。 それなのに、VC++でUNICODE対応の設定にするとwchar_tで文字列を扱うようなので、UTF-8がどういう扱いになっているのかよくがわからないのです。 どなたかお答え頂けないでしょうか。 よろしくお願いします。

  • c言語の __FILE__ について

    事前定義マクロの__FILE__で取得した文字列のchar型ですか?それともwchar_t型ですか?  これは処理系に依存するのでしょうか? ちなみに現在使用処理系はVisual c++ 2005 Express Editionです。

  • C++Builder 2009 テキストボックスの文字列取得

    Editは、テキストボックスです。 Editには、"12345"の半角文字列が入っています。 これを、C言語の文字列として取得しようとしました。 このときのソースコードは、次の通り。 -------- char *ptr1 = new char[Edit->Text.Length()+1]; //独自領域にセーブ strcpy(ptr1, Edit->Text.c_str()); //ptr1にアドレスをコピー -------- このstrcpyの行で、エラーが出てしまい、対処に困っています。     ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ E2034 'wchar_t *' 型は 'const char *' 型に変換できない E2342 パラメータ '__src' は const char * 型として定義されているので wchar_t * は渡せない -------- Edit->Textで取得した文字列を、"12345\0"といった具合で処理をしたいのですが、どのようにしたらいいのでしょうか? 追記 「C++Builder 2009」以前のバージョンでは、難なく取得できていた。 同じソースコードなのに、何故かエラーになる。

  • MFC C++ と C++/CLI の文字列

    VS2008です。 Library: NativeC++ with MFC -> DLL   ↑↓ Wrapper: C++/CLI with .NET -> DLL   ↑↓ Appli: VB.NET with .NET -> EXE 元々、ActiveXコントロール(非GUI利用)だったNativeC++で書かれたLibraryを MFC DLLとしてビルドし、Wrapper 経由で Appli から使用できるよう 移植をしています。 Library から必要な関数を dllexport し、wrapper から参照し、 wrapper を Appli が参照して、使用できるようにしました。 int型を引数に取り、結果として返す関数は期待どおり動作しますが、 文字列だと上手く行きません。 Wrapper/Appli は System.CString で統一したいのですが、 Library ではどのような型として宣言すれば文字列のやり取りができるでしょうか。 ( 引数・戻値の両者 ) CString wchar_t* char* System.String ALT::CStringT basic_string _bstr_t CComBSTR LPCTSTR LPTSTR PCTSTR PTSTR LPCWSTR LPWSTR PCWSTR PWSTR BSTR… なお、Library で下記のようにエクスポートし __declspec(dllexport) BSTR test(LPCTSTR data); wrapper で BSTR hoge(LPCTSTR value){ return test(value); } と宣言すると、wrapperのビルドで下記のエラーが表示されます。 エラー 1 error LNK2028: 未解決のトークン (0A000B39) "wchar_t * __cdecl test(wchar_t const *)" (?test@@$$FYAPA_WPB_W@Z) が 関数 "public: wchar_t * __clrcall wrap::hoge(wchar_t const *)" (?hoge@C3dlib@@$$FQ$AAMPA_WPB_W@Z) で参照されました。 wrapper.obj wrapper エラー 2 error LNK2019: 未解決の外部シンボル "wchar_t * __cdecl test(wchar_t const *)" (?test@@$$FYAPA_WPB_W@Z) が 関数 "public: wchar_t * __clrcall wrap::hoge(wchar_t const *)" (?hoge@C3dlib@@$$FQ$AAMPA_WPB_W@Z) で参照されました。 wrapper.obj wrapper エラー 3 fatal error LNK1120: 外部参照 2 が未解決です。

専門家に質問してみよう