gooドクター有料プランが1ヶ月間無料!

TextFieldParserによる固定長テキストファイルの読込で、
桁数を文字数ではなく「byte数」で指定する方法を教えてください。
(FileOpen関数などではなく、あくまでもTextFieldParserを使用するのが前提です)
以下に、文字数指定による読込のコードを記述します。
よろしくお願いします。

'VBのコード-----------------------------------------------
  Public Shared Sub Main()
    Using reader As New TextFieldParser("C:\test.txt", Encoding.GetEncoding("SHIFT_JIS"))
      reader.TextFieldType = FieldType.FixedWidth
      reader.SetFieldWidths(2, 7, 2)

      Dim currentFields() As String
      While Not reader.EndOfData
        Try
          currentFields = reader.ReadFields() ' 一行読込
          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
'VBのコード ここまで------------------------------------

<読み込む固定長ファイル>
01やまだいちろう26
02やまだじろう 23


<実行結果>
01
やまだいちろう
26
02
やまだじろう
23


>reader.SetFieldWidths(2, 7, 2)
この部分を
>reader.SetFieldBytes(2,14,2) '関数名は適当
このように指定できないか、と考えています。

gooドクター

A 回答 (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
    • good
    • 0
この回答へのお礼

回答いただきありがとうございます。
やはりTextFieldParser自体には、SHIFT_JISでの全角を2byteで扱えるような機能はないという事のようですね。
固定長やCSVを読み込むことに特化したクラスなのでもしや、
と思ったのですが…

しかし、x415f484fさんに提示していただいたコードは代替案として
たいへん参考になります。
TextFieldParserにこだわらず、一行丸々読み込んでから
バイト配列に入れてしまえばよかったんですね。
VBFixedStringとFileOpenを使う方法などを模索していましたが、
こちらのほうがしっくりきそうです。
ありがとうございました。

お礼日時:2008/03/11 10:18

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

gooドクター

このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング