文字列の注意点(その1)

VB5の文字列(String型)はワイド文字(ユニコード,16bit)を使用しています。
C++Builder1.xやDelphi3.xの文字列(AnsiString型)は2バイト文字セット(DBCS)を使用しています。
Delphi3.xは WideString 型の文字列にするとワイド文字(ユニコード,16bit)が使用できます。

それぞれの言語と文字列型で、内部データ構造が変化するので注意が必要です。

用語集
 1バイト文字セット=SBCS(single-byte character set)
 2バイト文字セット=DBCS(double-byte character set)
 マルチバイト文字セット=MBCS(multi-byte character set)
 ワイド文字=ユニコード

かなぁ(^^;
間違えているかもしれません。ヘルプやBooks Onlineの用語が難しくて苦労しますね。

 


VBの場合

String 型を使用

"ABCあいう" の内部データ
バイト数 1 2 3 4 5 6 7 8 9 10 11 12
1バイト毎のデータの並び
(16進)
41 00 42 00 43 00 42 30 44 30 46 30
文字数 1 2 3 4 5 6
実際の文字 "A" "B" "C" "あ" "い" "う"

確認に使用したコード


Private Sub Command1_Click()
    Dim length As Integer
    Dim cnt As Integer
    Dim char1 As String
    Dim ascii As Integer
    Dim swork As String
    Dim msg As String
    
    '* Stringの内容をチェック
    swork = "ABCあいう"
    
    msg = "元の文字列=" + swork + Chr(13) + Chr(10)
    length = LenB(swork)
    For cnt = 1 To length
        ' 1バイト取り出して、文字コードに変換する
        char1 = MidB(swork, cnt, 1)
        ascii = AscB(char1)
        ' 文字コードを16進数の文字列に変換する
        msg = msg + Right("00" + Hex(ascii), 2) + ","
    Next cnt
    Call MsgBox(msg)
    
End Sub


C++Builderの場合

AnsiString 型を使用

"ABCあいう" の内部データ
バイト数 1 2 3 4 5 6 7 8 9 10
1バイト毎のデータの並び
(16進)
41 42 43 82 A0 82 A2 82 A4 00
文字数 1 2 3 4 5 6 NULL
実際の文字 "A" "B" "C" "あ" "い" "う" ヌル
ターミ
ネーター

確認に使用したコード


//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  // AnsiStringの内容をチェック
  AnsiString swork = "ABCあいう";
  AnsiString msg = "元の文字列=" + swork + "\xd\xa";
  int len = swork.Length() + 1;
  for(int cnt = 1; cnt <= len; cnt ++ ){
    // 1バイト取り出して、文字コードに変換する
    int ascii = int(swork[cnt]) & 0xff;
    // 文字コードを16進数の文字列に変換する
    msg += IntToHex(ascii, 2) + ",";
  }
  ShowMessage(msg);

}
//--------------------------------------------------------------------------- 


Delphiの場合

AnsiString 型を使用

"ABCあいう" の内部データ
バイト数 1 2 3 4 5 6 7 8 9
1バイト毎のデータの並び
(16進)
41 42 43 82 A0 82 A2 82 A4
文字数 1 2 3 4 5 6
実際の文字 "A" "B" "C" "あ" "い" "う"

確認に使用したコード

procedure TForm1.Button1Click(Sender: TObject);
var
  len: Integer;
  cnt: Integer;
  ascii: Integer;
  swork: AnsiString;
  msg: AnsiString;
begin
  // AnsiStringの内容をチェック
  swork := 'ABCあいう';
  msg := '元の文字列=' + swork + #13#10;
  len := Length( swork );
  for cnt := 1 to len do
  begin
    // 1バイト取り出して、文字コードに変換する
    ascii := Ord( swork[cnt] );
    // 文字コードを16進数の文字列に変換する
    msg := msg + IntToHex( ascii, 2) + ',';
  end;
  ShowMessage( msg );

end;

 

WideString 型を使用

"ABCあいう" の内部データ
バイト数 1 2 3 4 5 6 7 8 9 10 11 12
1バイト毎のデータの並び
(16進)
41 00 42 00 43 00 42 30 44 30 46 30
文字数 1 2 3 4 5 6
実際の文字 "A" "B" "C" "あ" "い" "う"

確認に使用したコード

procedure TForm1.Button2Click(Sender: TObject);
var
  len: Integer;
  cnt: Integer;
  ascii: Integer;
  swork: WideString; // ワイド文字対応
  msg: AnsiString;
  S: array[0..256] of Char;
begin
  // WideStringの内容をチェック
  swork := 'ABCあいう';
  msg := '元の文字列=' + swork + #13#10;
  len := Length( swork );
  for cnt := 1 to len do
  begin
    StrLCopy( S, PChar( @swork[cnt] ), 2 );
    // 1バイト取り出して、文字コードに変換する
    ascii := Ord( S[0] );
    msg := msg + IntToHex( ascii, 2) + ',';
    ascii := Ord( S[1] );
    msg := msg + IntToHex( ascii, 2) + ',';
  end;
  ShowMessage( msg );

end;

戻る