おはようございます。
VBでの文字列宣言の仕方についてご教授下さい。
C言語でいうChar配列のような定義方法をVBでは
どのように宣言すればよいのでしょうか。
例えばC言語でデータファイル.dat内に 文字列ABCDEFGという
データのみが格納されているとします。
Char str[8]と定義した配列にRead関数で文字列(ABCDEFG)を
取得すると以下のようなメモリーイメージになります。
str=
0 1 2 3 4 5 6 7
|---|---|---|---|---|---|---|
| A | B | C | D | E | F | G |
|---|---|---|---|---|---|---|
ch = str[2] で'C'を取得することが出来ます。
これをVBで実現するためには、どのような変数定義で
どのようなファイル取得すればよいのでしょうか。
例えばVBで以下のように試してみましたが、
どうしても???位置がわかりませんでした。
Dim str(8) As String ←???
Open ファイル名 For Input As #ファイル番号
Line Input #ファイル番号, ???
Close #ファイル番号
結局、何がやりたいかというと
ファイルから取得したデータを指定バイト毎に切り分けて
フォーム上にある異なるコントロール(複数のテキストボックス)に
表示したいのです。
説明不足、意味がわからないところがあるかと思いますが
ご教授お願い致します。
ま・・・こういうものがほしいのでしょうか?
Option Explicit
Private Sub Command1_Click()
Dim hnum As Integer
Dim pnum As Integer
Dim mnum As String'文字型変数宣言
hnum = FreeFile
Open App.Path & "\Read.txt" For Input As #hnum'指定ファイルから読み込み
For pnum = 0 To 5
Line Input #hnum, mnum
text1(pnum).Text = mnum
Next pnum
Close #hnum
End Sub
Private Sub Command2_Click()
Dim hnum As Integer
Dim pnum As Integer
hnum = FreeFile
Open App.Path & "\Read.txt" For Output As #hnum’指定ファイルに保存
For pnum = 0 To 5
Print #hnum, pnum
Next pnum
Close #hnum
End Sub
テキストボックスを一個貼り付けてコピペするとコントロール配列ができますのでそれを6個つけてコマンドボタンを2個つけてやってみてくださいな
とりあえずテキストボックスに書いたことを保存したり読み出したりすることはできます
CとVBでは配列の扱い方が違うので、そのままやろうとすると挫折しますよね(^^;
読み込むデータはテキストでしょうか?バイナリーでしょうか?
テキストだったら文字列型の単純変数にどっかり読み込んでMid()関数で必要な文字を取り出せばいいかと思います。
バイナリーの場合だったら
Dim DataBuf() As Byte でとりあえずバイト型の宣言だけして
FileLen() 関数でファイル長を取得
Redim Databuf() (malloc見たいなモノですかね)で読込に必要な量を確保します
バイナリー形式でファイルをオープンし(この辺はヘルプ見てください)
その後InputB()で読み込んだら、databuf()でアクセスできると思います
(ただしこれはバイナリーデータなので、最後に文字変換関数で上手いことアレしてください)。
SKYさん、化石さん、ご教授ありがとうございます。
とりあえずテキストデータの読込みでしたので
Mid関数で問題解決しそうです。
確認してみます!
あと、バイナリーで取得した場合のも試してみます。
>最後に文字変換関数で上手いことアレしてください
アレって・・・ 色々試してみます^^; (strConvとか)
バイト型もあるけどね。
Dim mNum() As Byte 'バイト型変数宣言
でもファイルの読み取りとか含めて VB で扱うには
String の方が何かと便利だと思ってますが…。
あとはバイト型を対象とした文字列操作関数で切り分けるとか…
対象 | String | Byte
----------------------------------
| Asc | AscB
| Chr | ChrB
| Input | InputB
| InStr | InStrB
| Left | LeftB
| Right | RightB
| Len | LenB
| Mid | MidB
失礼・・・今試したら失敗してた^^;
Option Explicit
Private Sub command3_Click()
Dim nnum As Integer
For nnum = 0 To 5 'textBoxの0〜5までを空白にする
text1(nnum).Text = ""
Next nnum
End Sub
Private Sub command2_Click()
Dim fnum As Integer
Dim nnum As Integer
Dim hnum As String
fnum = FreeFile
Open App.Path & "\24.txt" For Input As #fnum
For nnum = 0 To 5
Line Input #fnum, hnum '1行づつ改行するまで読み込む
text1(nnum).Text = hnum 'textBoxの0〜5まで繰り返し
Next nnum
Close #fnum
End Sub
Private Sub command1_Click()
Dim fnum As Integer
Dim nnum As Integer
fnum = FreeFile
Open App.Path & "\24.txt" For Output As #fnum
For nnum = 0 To 5
Print #fnum, text1(nnum).Text 'textboxの0~5まで保存
Next nnum
Close #fnum
End Sub
これなら大丈夫なはず・・・
> C言語でいうChar配列のような定義方法をVBでは
> どのように宣言すればよいのでしょうか。
C言語のChar配列、すなわち「文字の配列」は、他の言語においては、
「文字列」という概念で処理される事が多いです。
「文字列」としての意味であれば、
Dim S As String
S = "ABCD"
とだけ書けばOKです。
しかし何らかの理由で、「文字列」ではなく、Cのように「文字の配列」として
扱いたいならば、以下のようにします。
まず、VB.NET であれば、
Dim C() As Char
のように定義します。Char型は、特定の1文字を表すデータ型です。
この変数に一括代入するなら、
C = New Char() {"A"c, "B"c, "C"c, "D"c}
のように、一文字ずつ指定していくか、もしくは
C = "ABCD".ToCharArray()
のように、文字列(String型)のToCharArrayメソッドで変換します。
(もっとも、今回の質問文から察するに、.NETでは無さそうですけれども)
VB6以下、あるいはVBAの場合は、C言語の Char に相当するデータ型は
ありません。強いて言えば、固定長文字列型を使って、
Dim C() As String * 1
ReDim C(3)
C(0) = "A"
C(1) = "B"
C(2) = "C"
C(3) = "D"
と書けば、C言語の Char に近いイメージになりますが、メリットは無いでしょう。
まぁ、APIを使うためには、C言語の char型(≠Char型)に相当する
「Byte型」の配列で代用する事はありますけれどね。
String型をByte型配列に変換する場合は、
Dim C1() As Byte
C1 = "ABCD"
もしくは、
Dim C2() As Byte
C2 = StrConv("ABCD", vbFromUnicode)
という形式を使います。
(前者はUnicode文字列、後者はShift_JIS文字列のバイトデータになります)
> Dim str(8) As String ←???
> Open ファイル名 For Input As #ファイル番号
> Line Input #ファイル番号, ???
> Close #ファイル番号
Line Input #を使う場合は、「文字の配列」ではなく「文字列」にします。
つまり、
Dim S As String
で宣言して、
Line Input #ファイル番号, S
という感じですね。
> ファイルから取得したデータを指定バイト毎に切り分けて
バイト単位ならば、(C言語の)Char ではなく、charなのでは?
Charだとしたら、「文字単位」ですよね。
文字単位で扱いたいなら、Mid関数を使ってみて下さい。
C = Mid("ABCD", 1, 1) 'Cには "A" が入る。
C = Mid("ABCD", 2, 1) 'Cには "B" が入る。
C = Mid("ABCD", 3, 1) 'Cには "C" が入る。
バイト単位で扱いたいなら、先に記述した方法で、Stringデータを
Byte配列に変換してみてください。あるいは、Open For Input ではなく、
Open For Binary を使えば、最初からByte配列にて得る事もできます。
SKYさん、特攻隊長まるるうさん、化石さん、魔界の仮面弁士さん、アドバイスありがとうございます。
シーケンシャルによるデータ読込みは以下の内容で出来ました。
--- 外部ファイル(SampleData.Dat) ---
11111あああああ0000000001
--- 画面コントロール ---
Text1, Text2, Text3 → 配列化(0〜2), 配列名→Text
Command1
--- General領域 ---
TYPE SAMPLE
m_xxx As String
m_yyy As String
m_zzz As String
END TYPE
Sub Command1がクリック時
Dim 格納配列 As String
Open "F:\SampleData.Dat" For Input As #ファイル番号
Line Input #ファイル番号, 格納配列
Call 表示関数(格納配列)
End Sub
Sub 表示関数(str As String)
Dim sample As SAMPLE
Dim i As Integer
sample.m_xxx=Mid(str, 1, 5)
sample.m_yyy=Mid(str, 6, 10)
sample.m_zzz=Mid(str,16, 10)
<中略>
Text(0).Text=sample.m_xxx
Text(1).Text=sample.m_yyy
Text(2).Text=sample.m_zzz
End Sub
上記で表示することができましたが
別のデータファイル(文字コードの複合)をバイナリーモードで
(複合といっても上記のデータファイルで'あああああ'がUnicodeです)
取得しようとすると以下のエラーがでました。
Dim sz As Long
Dim bstr() As Byte
Open ファイル名 For Binary Access Read As #ファイル番号
sz=LOF(ファイル番号)
ReDim bstr(sz-1)
Get #ファイル番号, ,bstr
Call 表示関数(bstr) ←ここで "ByRef引数の型が一致しません"と出てしまう
※構造体は上記と同じ構造を使用します(TYPE SAMPLE)
※構造体内の変数型も同様です
Sub 表示関数(bstr() As Byte)
Dim sample As SAMPLE
sample.m_xxx=Mid(bstr, 1, 5) ←ここ以前でエラーなので自信なし
sample.m_yyy=Mid(bstr, 6, 10)
sample.m_zzz=Mid(bstr,16, 10)
End Sub
すいません、お気付きの点がありましたらご教授お願いします。
非常に長くなってしまい申し訳ありません。。
> "ByRef引数の型が一致しません"と出てしまう
ByRef定義された引数に、(式や定数ではなく)変数を渡す場合、
呼び出し側と呼び出される側のデータ型が一致していないと、
そのようなエラーが発生する事になります。
# 引数に、ByVal / ByRef の指定が無い場合、
# VB6では「ByRef」扱いとなります。
例えば、
Option Explicit
Private Sub Form_Load()
Dim bstr() As Byte
ReDim bstr(3)
Call Test(bstr)
End Sub
Private Sub Test(bstr() As Byte)
MsgBox "Test"
End Sub
というコードは正しく呼び出されますが、呼び出されるプロシージャを
Private Sub Test(bstr As Byte)
などという定義にした場合には、『ByRef引数の型が一致しません』の
エラーが発生するはずです。
ツイート | ![]() |