CString text = "あいう";
を
" あいう"
と処理して取得しようとしています。
CString text = "あいう";
stringstream s_txt;
s_txt << setw(10) << setfill(' ') << text;
text = s_txt.str().c_str(); //★
CStringではsetfillが使えず、
調べたところstringstreamならできそうだったので
上記のようにしました。
…が、★実行後のtextは" 00385514"でした。
そもそもやり方が間違っていそうな気はするんですが、
どうすれば空白埋めができるでしょうか?
それとも、こういうことはできないのでしょうか…
VC++6.0 MFCダイアログベースです。
よろしくお願いします。
・Formatで書式を"%10.10s"にして"あいう"を入れる
・GetLengthで文字数調べて足りない分だけInsertでスペースを挿入
どちらでもCStringにスペースを入れることができます
ご指摘の方法を試した所、できました!
setfillを使おうとするからいけなかったんですね…
みいさん、ありがとうございました。
/*
option:
-EHsc -DAFX_DLL
- or -
-EHsc -DAFX_DLL -DUNICODE -D_UNICODE
*/
#include <afxwin.h> // CString
#include <iostream> // cout, wcout
#include <iomanip> // setw, setfill
#include <sstream> // stringstream, wstringstream
using namespace std;
#ifndef UNICODE
int main() {
CString text = "あいう";
stringstream s_txt;
s_txt << setw(10) << setfill(' ') << text;
text = s_txt.str().c_str(); //★
cout << '[' << static_cast<const char*>(text) << ']' << endl; ;
}
#endif
> setfillを使おうとするからいけなかったんですね…
↓いけなくないですがー
#ifdef UNICODE
#include <locale>
int main() {
wcout.imbue(locale("japanese"));
CString text = "あいう";
wstringstream s_txt;
s_txt << setw(10) << setfill(L' ') << static_cast<const wchar_t*>(text);
text = s_txt.str().c_str(); //★
wcout << '[' << static_cast<const wchar_t*>(text) << ']' << endl; ;
}
#endif
> s_txt << setw(10) << setfill(' ') << text;
VC++6だと、ここの 「<< text」で、std::stringstream::operator<<(const void *)が
呼ばれている節があります。「<< static_cast<LPCTSTR>(text)」なら
std::operator<<(ostream &, const char *) が呼び出されるようですが。
※ MBCS版のみ調査。
気になったのでちょっと実験してみた所、operator const char *()による
型変換と、オーバーロードされたoperator<<()との組み合わせによって
妙なふるまいをすることが分かりました。
-----------------------------------------------------------------
/*
* 3つあるoperator<<()は、basic_ostream関連のoperator<<()に、
* 同様のプロトタイプを持つものがあります。
* (テンプレートパラメータや戻り値型は端折ってますが)
*/
#include <iostream>
struct X
{
// operator<<() その1
void operator<<(const void *) { std::cout << "X::operator(const void *)\n"; }
};
// operator<<() その2
template<typename T>
void operator<<(X &, const T *) { std::cout << "::operator<< <T>(X &, const T *)\n"; }
// operator<<() その3
void operator<<(X &, const char *) { std::cout << "::operator<<(X &, const char *)\n"; }
struct Y
{
operator const char *() const { return "hoge"; }
};
int main()
{
X x;
Y y;
x << y; // A
x << static_cast<const char *>(y); // B
std::cout << y << '\n';; // C
std::cout << static_cast<const char *>(y) << '\n'; // D
return 0;
}
-----------------------------------------------------------------
VC++6の場合、Aではoperator<<()その1が呼ばれ、Bではその3が呼ばれました。
また、Cでは文字列のアドレスが出力され、Dでは文字列の内容が出力されました。
一方、VC++2008とgcc-4.3.4の場合、A、Bではともにoperator<<()その3が
呼ばれ、C、Dではともに文字列の内容が出力されました。
さらに奇妙なことに、結局呼ばれることがないはずのoperator<<()その2の
定義を消すと、VC++6でもVC++2008やgccと同様の結果になりました。
まあ、C++98以前の処理系のVC++6に、C++98規格を持ち出して云々するのも
ナンセンスなのでやめておきますが、明示的にキャストしてやれば
期待通りになるのでひとまずの回避策になりそうです。
# というか、関数選択規則が複雑すぎるので、C++規格を引っ張り出して
# 検証するのが面倒臭いというのが本音だったり。
## ついでに言うと、Digital Mars C++ 8.42nではさらに違った挙動に。
## 何なんだ一体……
ツイート | ![]() |