- ベストアンサー
TextFieldParserの固定長桁数をバイト単位で指定する方法
- TextFieldParserを使用して、固定長テキストファイルの読み込み時に文字数ではなくバイト数で桁数を指定する方法について教えてください。
- 以下のVBのコードでは、reader.SetFieldWidthsを使用して文字数で桁数を指定していますが、reader.SetFieldBytesなどを使用してバイト数で指定することはできないでしょうか。
- 読み込む固定長ファイルの例と実行結果も示されています。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
もしかすると的外れかもしれないですが…… 要するに「02やまだ じろう 23」とか、半角が混じっているとおかしく なるので全角は二バイト文字として処理したいということでしょうか? > FileOpen関数などではなく、あくまでもTextFieldParserを使用するのが前提です UTF-8 などの必ずしも全角文字が 2 バイトと限らない文字コードを扱う 時点で「全角は 2 バイト」というのは破綻してしまうと思います。 # たしかに Shift_JIS なので全角は 2 バイトですが…… # 文字は全角も半角も一文字と数えるという仕様なのだと思われます。 一旦、一行全て読み込み、文字列をバイト配列に変換して処理するのは いかがでしょうか? 取り敢えず、こんな感じで貼られていたコードを部分的に変更してみま した。 ※ 見栄え上、全角文字列でインデントしてあります。 拙いコードですのが、ご容赦下さい。 REM 動作確認した時に関数にしたのでそのままです。 Sub ReadFile() Using reader As New TextFieldParser("C:\test.txt", Encoding.GetEncoding("SHIFT_JIS")) REM reader.TextFieldType = FieldType.FixedWidth REM reader.SetFieldWidths(2, 7, 2) reader.TextFieldType = FieldType.Delimited Dim currentFields() As String While Not reader.EndOfData Try REM currentFields = reader.ReadFields() ' 一行読込 REM 読み込みと同時に関数へ渡す currentFields = GetFieldString(reader.ReadLine, "SHIFT_JIS", 2, 14, 2) Dim currentField As String For Each currentField In currentFields Trace.WriteLine(currentField) Next Catch ex As MalformedLineException MessageBox.Show(ex.Message) End Try End While End Using End Sub Function GetFieldString(ByRef Str As String, ByRef strEncode As String, ByVal ParamArray Prams() As Integer) As String() Dim iPram As Integer Dim iIndex As Integer = 0 Dim iStrP As Integer = 0 Dim strArray As String() = {""} REM バイト配列に変換 Dim ByteArray As Byte() = Encoding.GetEncoding(strEncode).GetBytes(Str) For Each iPram In Prams REM 文字列に変換して文字列の配列に格納 strArray(iStrP) = Encoding.GetEncoding(strEncode).GetString(ByteArray, iIndex, iPram) iStrP = iStrP + 1 ReDim Preserve strArray(iStrP) iIndex = iIndex + iPram Next REM 余分な配列を除く ReDim Preserve strArray(iStrP - 1) Return strArray End Function
お礼
回答いただきありがとうございます。 やはりTextFieldParser自体には、SHIFT_JISでの全角を2byteで扱えるような機能はないという事のようですね。 固定長やCSVを読み込むことに特化したクラスなのでもしや、 と思ったのですが… しかし、x415f484fさんに提示していただいたコードは代替案として たいへん参考になります。 TextFieldParserにこだわらず、一行丸々読み込んでから バイト配列に入れてしまえばよかったんですね。 VBFixedStringとFileOpenを使う方法などを模索していましたが、 こちらのほうがしっくりきそうです。 ありがとうございました。