文字列操作系の挙動について

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
Canalime
記事: 8
登録日時: 2005年6月03日(金) 13:39

文字列操作系の挙動について

#1 投稿記事 by Canalime »

どうも文字列操作がうまくいきません
以下のようなコードで
TWArray[UseSet].WPath = "C:\AAA\"
WFilePath ="BBB.exe"
というような状況下に於いて以下のコードを実行した場合
WFilePath ="C:\AAA\BBB.exe"
となりそうなのですが、何故か
WFilePath ="C:\AAA\"
となってしまします。

コード: 全て選択

Sub PWEx(ByVal WFilePath As String)
   If InStr(1,WFilePath,":") = 0 _
      Then WFilePath = TWArray[UseSet].WPath & WFilePath
また、
.WPath = "C:\AAA"
という状況下に於いて以下のコードを実行した場合
.WPath = "C:\AAA\"
となりそうなのですがデバッグしてみると
Right$(.WPath,1) = ""
となります、"A"のはずなんですが…

コード: 全て選択

   If .WPath <> "" Then
      If Right$(.WPath,1) <> "\" Then .WPath = .WPath & "\"
   End If
上記2項目の共通点は変数は、String型で
変数に格納したパスやファイル名はGetPrivateProfileStringで
iniファイルから拾ってきた文字列ということです。
デバッグウィンドウの値を見ると文字列自体は
それぞれちゃんと格納されているようなのですが何が悪いのでしょうか?
--/* from Canalime */--  
hira
記事: 203
登録日時: 2005年5月31日(火) 20:14
お住まい: 兵庫県
連絡する:

Re: 文字列操作系の挙動について

#2 投稿記事 by hira »

GetPrivateProfileString関数など、文字列を返すAPIを使う場合、まずはString型にZeroString()の戻り値を代入するか、ポインタ型にmalloc()やcalloc()の戻り値を代入して領域を確保します。

今回の問題ですが、例えば(APIからは離れてください) ZeroString(8) の戻り値をString型変数aに代入すると、aの内容は

00 00 00 00 00 00 00 00

という構造をすることになります。
ここに "1234" という文字列が返されたとき、

31 32 33 34 00 00 00 00

構造がこのようになります。
つまり、文字数が余っているときには、末尾にNULL文字が残るのです。
このNULL文字は一般的には文字列の終端を表すため、デバッグウィンドウでもNULL文字以降は表示されません。
今回の例に戻ると、1つ目の事例は

"C:\AAA\---…---" & "BBB.exe" (わかりやすいように、ここではハイフンをNULL文字として説明します)
= "C:\AAA\---…---BBB.exe"
となっており、
2つ目の事例は

Right$("C:\AAA---…---",1) = "-" となるため、いずれも結果としては正しいのです。
とはいえ、意図しない結果であることは事実ですので、

TWArray[UseSet].WPath=MakeStr(TWArray[UseSet].WPath)

.WPath=MakeStr(.WPath)

のように、MakeStr関数を使えば解決できます。
(GetPrivateProfileString関数で拾った文字列に対して、これを実行すればOKです。他の文字列を返す関数でも同様のことがいえます。)
Canalime
記事: 8
登録日時: 2005年6月03日(金) 13:39

お陰様で

#3 投稿記事 by Canalime »

大変わかりやすい解説をして頂き有り難う御座いました。
幸い、GetPrivateProfileStringを都度書くのが面倒だったので
関数にしていた為、1行書き換えるだけで解決しました。
おかげで、ChDirを使って誤魔化すような真似をせずに済みました。

そっか…NULLだったのか。
--/* from Canalime */--  
返信する