シリアライズ関数を使うと、保存の際、頭に「豆腐記号」が入る? ちなみにこの文字コード値は一定していない。
漢字の場合、最後に・が残るが、これは何かの半角文字である。 エンターキーを押せば消えるのは、 これにより2バイトの空文字と判断されるためではないか。
いずれにせよ、以下のように実装しなおす。
void CDocViewDoc?::BackSpace?() { int index = 0; int kanji_stat = 0; unsigned char uch; int len = strData.GetLength?(); while(index < len) { uch = (unsigned char)strData.GetAt?(index);
if(uch >= 0x81 && uch <= 0x9f || uch >= 0xe0 && uch <= 0xfc) { kanji_stat = 2; } else if(uch == 0x0d) { kanji_stat = 1; } else{ kanji_stat = 0; }
switch(kanji_stat) { case 0: AfxMessageBox?("半角文字である"); strData.Delete(strData.GetLength?() - 1, 1); break; case 1: AfxMessageBox?("改行文字である"); strData.Delete(strData.GetLength?() - 1, 1); break; case 2: AfxMessageBox?("漢字である"); strData.Delete(strData.GetLength?() - 2, 2); break; } len = strData.GetLength?(); // by ISHIDA 先頭文字から削除したので、もう一度長さを計りなおす。 }
}
}
10章
手作業で 1 ユーザーメッセージ、2 メッセージマップ、3 ハンドラ関数を実装。
ハンドラ関数は、1,2がすんだ状態であれば、たとえばP361は CMaiFrame?.cpp に直接
LRESULT CMainFrame?::
と打ち込むと、関数選択ダイアログが出てくるので、そのまま実装する。
5月24日 wsprintf
/* int num = 10; CString nums;
wsprintf((const char*)nums, "%i", num); wsprintf(nums, "%i", num); 'wsprintfA' : 1 番目の引数を 'class CString' から 'char *' に変換できません。 (新しい機能 ; ヘルプを参照) この変換を実行可能なユーザー定義変換演算子がないか、または演算子を呼び出せません。
/* wsprintf((char*)nums, "%i", num); error C2440: 'type cast' : 'class CString' から 'char *' に変換することはできません。(新しい動作 ; ヘルプを参照) この変換を実行可能なユーザー定義変換演算子がないか、または演算子を呼び出せません。
/* wsprintf((const char*)nums, "%i", num); 'wsprintfA' : 1 番目の引数を 'const char *' から 'char *' に変換できません。 (新しい機能 ; ヘルプを参照) 変換で修飾子が失われます。 (constが属性が消えることになってしまう by ISHIDA)
たとえば int sprintf( char *buffer, const char *format [, argument] ... );
この関数では、2番目の引数(コピー元の文字列にconst属性があるから、 コピー先である第一引数にCString 文字クラスのオブジェクトをおいた場合、char型へのキャストと共に、const指定が必要となる。
void Func( CString& str, int i ) { char buffer[100]; wsprintf( buffer, "i = %i", i ); str = buffer; }
あるいは str.Format("i= %i", i); Subject: [vcpp 00000013] CString (Re: Call DLL)
解答は Visual C++ マニュアル ”文字列 : CString 演算と C スタイルの文字列” に。
また柏原C++ P.87
const char *p_moji = new char[10]; << この式は実体はconst化するが、ポインタは変更可能。 strcpy(p_moji, "ABCDE"); << 1 番目の引数を 'const char *' から 'char *' に変換できません。
一番目の引数の「実体」を変更しようとするからエラーとなる。この引数のポインタであれば変更可能。だから、さらにポインタ方にキャストするというのが原理。
要するにC、C++ 環境でも、const宣言した変数のポインタを、たとえば const属性されていない別の参照変数に代入したりなんかすると、後者の方 で前者の実体を勝手に変更されるような操作が認められたりするから、そ れは許されない。だから後者にもconst属性が必要である。それと同じよう な理屈かと、納得できたような気がします。ともかく、お騒がせしまし た。m(__)m
const char moji* = "A"; char &ref_moji = moji; << エラー const char &ref_moji = moji; << OK
6月15日 ワイド文字 と マルチバイト文字
HexString?プログラムより
ch1 = str.GetAt?(0); ch2 = str.GetAt?(1);
unsigned char toWch[2]; toWch[0] = ch1; toWch[1] = ch2; wchar_t wch; mbtowc(&wch, (char*)(const char *) toWch, 2);
str5.Format("最初の全角文字のユニコードは \"%04X\"",wch);
/* 以下はエラー
mbtowc(&wch, toWch,2);
E:\Program\cpp\HexString?\Change.cpp(58) : error C2664: 'mbtowc' : 2 番目の引数を 'unsigned char [2]' から 'const char *' に変換できません。 (新しい機能 ; ヘルプを参照) 指示された型は関連がありません; 変換には reinterpret_cast、 C スタイル キャスドたは関数スタイルのキャストが必要です。
6月25日 トークン化 strtok
strtok には最初の文字列を残して、残りを削除する効果がある?
SYNTAX.VCFILE プロジェクトより
char seps[] = "!$\"\u00a3%^&*()_+=#{}[]'`/?.,:; \t\n"; char crlf[] = "\r\n"; char *token;
m_text = ""; while(fin.ReadString?(buff,1000) != NULL) { m_text = m_text + buff; }
token = strtok((char *)(const char *)m_text, seps);
while( token != NULL ) { char *m_token = token; m_list.AddString?(m_token); token = strtok( NULL, seps ); }
UpdateData?(FALSE);
m_text エディットボックスに 表示されるのは、 ファイルから読み込んだ文字列のうち、最初のトークンまでの一単語だけ。 m_list リストボックスには、全てのトークンが表示される。
ただし strtok の処理をネストすることはできない! たとえば Tag プログラムでは、元テキストを読み込み、 それを スペースごとに strtok かけ、その過程で、Tag()関数へトークンを渡しているが、そのTag()関数内部には、別の strtok 関数があるので、 エラーとなる。