• 締切済み

ファイルから指定位置の1文字を読み込むには?(VB2008)

D:\Temp\ForGrep.txt Ah Love! could you and I with Fate conspire To grasp this sorry Scheme of Things entere, Would not we shatter it to bits -- and then Re-mould it nearer to the heart's Desire! このようなファイルを読み込んで出力する演習をしています。 ' ============================== ' 全ての行を読み込んで出力する ' ============================== Module theGrap   Sub Main()     Dim iNow As Integer = 0     Dim iNext As Integer = 0     Do       iNow = iNext       Debug.Print(ReadLine("D:\Temp\ForGrep.txt", iNow, iNext))     Loop Until iNext = -1   End Sub End Module ReadLine 関数でファイルの先頭0バイト目から1行を読み込む。 ReadLine 関数は、次の行が存在する可能性があれば次の行の開始バイトを iNext に代入。 ReadLine 関数は、次の行が存在しなければ iNext には -1 を代入。 聞きたいのは、あるポジションから1文字づつ行末まで読み込む方法です。 ' ---------------------------------------- ' ファイルから指定位置の1文字を読み込む ' ---------------------------------------- Private Function GetString(ByVal fs As FileStream, _               ByVal iPP As Integer) As String   Dim c As String = ""   Dim d As String = ""   Dim Buf(1) As Byte   Dim ec As Encoding = Encoding.Default   ' --------------------------------   ' 指定の位置より2バイト読み込む   ' --------------------------------   fs.Seek(iPP, SeekOrigin.Begin)   fs.Read(Buf, 0, Buf.Length)   c = ec.GetString(Buf)   ' ----------------------------------------------   ' 指定の位置より1バイト戻って2バイト読み込む   ' ----------------------------------------------   If iPP > 0 Then     fs.Seek(iPP - 1, SeekOrigin.Begin)     fs.Read(Buf, 0, Buf.Length)     d = ec.GetString(Buf)   End If   Return If(d.Length = 1, d, c.Substring(0, 1)) End Function 今、私は、このように非常にややこしい手順で1文字づつ読み込んでいます。 なんか、とんでもない無駄なことをしているような気がします。 多分、同じことが1行で出来るんではないかと思います。 「そんなややこしいことをしなくて、このようなやり方で」を教えて下さい。

noname#140971
noname#140971

みんなの回答

  • tom11
  • ベストアンサー率53% (134/251)
回答No.3

こんにちは、 表題とは違いますが。 >このようなファイルを読み込んで出力する演習をしています。 ここの部分に着目して、 >多分、同じことが1行で出来るんではないかと思います。 ここの部分から、以下のコードを書きました。 Module Module1 Sub Main() Dim fn As String = "C:\Documents and Settings\*****\My Documents\*****\goo_teach.txt" Dim line As String = My.Computer.FileSystem.ReadAllText(fn) Console.WriteLine(line) End Sub End Module 問題の英文の入っているファイルの名(goo_teach.txt)を、 読み込んで、コンソールに、すべて出力します。 ファイルに入っている文字が、全部変数lineに入っているので、 目的の文字を探したいなら、lineから、 探せばいいかと思いますが。 こんなことですか???

noname#140971
質問者

お礼

VB.Net とやらを知って50日。 ともかく、色んな手法があって当惑。 組み込み関数にMyなどなど。 初学者の私は、余りのメニューの多さに幻惑されっぱなし。 で、でも、マイクロソフトの厨房では .Net ライブラリが盛り付けられているだけのよう。 そういう事情なら、私も、組み込み関数とかMyとかは演習対象から除外しました。 で、今は、あくまでも .Net ライブラリが関心事です。 ど素人は、それほどに「あっちも、こっちも」という余裕はありません。 この辺りをご理解下さい。 さて、.Net ライブラリにターゲットを絞る大見栄をきっても固定長ファイルだけは別。 しかし、非固定長ファイルは、StreamReaderとTextReaderとが演習対象。 そういう結論に達しました。 で、質問は、My.Computer.FileSystemや組込関数のGetLineメソッド(あればですが)の自作。 そういうことですので宜しくお願いします。

回答No.2

すまん、勘違いした。撤回。

noname#140971
質問者

お礼

全容を示ます。 Module mdlFileSystem   Function ReadLine(ByVal aFile As String, _            ByVal iNowPosition As Integer, _            ByRef iNextPosition As Integer) As String     Dim aChar As String     Dim aChars As String = ""     If File.Exists(aFile) Then       Try         Using fs As FileStream = New FileStream(aFile, FileMode.Open, FileAccess.Read)           Do             aChar = GetString(fs, iNowPosition)             If aChar <> Chr(13) Then               aChars &= aChar             Else               iNowPosition = iNowPosition - 1               Exit Do             End If             iNowPosition += txt.LenB(aChar)           Loop While iNowPosition < fs.Length And aChar <> Chr(13)           iNextPosition = NextPosition(fs, iNowPosition)           fs.Close()           Return aChars         End Using       Catch ex As IOException         MsgBox(ex.Message & "(ReadLine)", , "告知:")         Return ""       End Try     Else       Return ""     End If   End Function   Private Function NextPosition(ByVal fs As FileStream, ByVal iP As Integer) As Integer     If (GetString(fs, iP + 2) = Chr(10) Or GetString(fs, iP + 2) = Chr(13)) And (GetString(fs, iP + 1) = Chr(10) Or GetString(fs, iP + 1) = Chr(13)) Then       iP += 3     ElseIf GetString(fs, iP + 2) = Chr(10) Or GetString(fs, iP + 2) = Chr(13) Then       iP += 2     Else       iP = -1     End If     Return iP   End Function   Private Function GetString(ByVal fs As FileStream, ByVal iPP As Integer) As String   ・・・・・   End Function End Module

回答No.1
noname#140971
質問者

お礼

iNextPosition が -1 であるべき時になっていないなどのバグがあります。 が、問題はあくまでも「ファイルから指定位置の1文字を読み込む」です。 「.NET の開発者達が英語圏だから仕方ないのじゃないの!」 という感想でも構いません。 宜しくお願いします。

関連するQ&A

  • VB2008 ファイルから指定位置の文字を読み込む方法??

    D:\Temp\Test.txt abc123あいう亜伊宇 [イミディエイトウインドウ] ? FileSeek("D:\Temp\Test2.txt", 1) "a" ? FileSeek("D:\Temp\Test.txt", 7) "あ" ? FileSeek("D:\Temp\Test.txt", 8) "あ" 今、FileStream の Seek メソッドを利用した指定位置の文字を1文字だけ戻す関数を作成。 なんとか動作だけはしています。 そこで、私が質問したいのは日本語の扱いのエレガントな方法です。 Seek メソッドでは2バイト文字の1バイト目と2バイト目とを読むケースが発生します。 私は、いずれの場合も"□・"とかではなく"あ"を戻させたいと思っています。 そのために私が考えた方法は次ようです。 ' -------------------------------- ' 指定の位置より2バイト読み込む ' -------------------------------- fs.Seek(p - 1, SeekOrigin.Begin) fs.Read(Buf, 0, Buf.Length) C = ec.GetString(Buf) ' ------------------------------------------ ' 指定の位置より1つ戻して2バイト読み込む ' ------------------------------------------ If p > 1 Then   fs.Seek(p - 2, SeekOrigin.Begin)   fs.Read(Buf, 0, Buf.Length)   D = ec.GetString(Buf) End If ・・・・・ ・・・・・ FileSeek2 = If(Len(D & "") = 1, D, Left(C, 1)) 仮に、最初の読み込みで3バイトを読み込んで2バイト目が何なのかを判別できると・・・。 そうすれば、2度読みする必要はないと思います。 そこで、その方法をご存じであればコードを含めて教えて頂ければ幸いです。

  • VB2008: ファイルから1行づつ読み込む関数のバグの修正方法?

    ' ========================================== ' 全ての行を読み込んで "" 行以外を出力する ' ========================================== Module theGrap   Sub Main()     Dim iNow As Integer = 0     Dim iNext As Integer = 0     Dim aLine As String = ""     Do       iNow = iNext       aLine = FGets("D:\Temp\Test4.txt", iNow, iNext)       If aLine = "" Then Continue Do       Debug.Print(aLine)     Loop Until iNext = -1   End Sub End Module [イミディエイト ウインドウ] 123あいうえお90 123かきくけこ90 123さしすせそ90 と、成功しています。 ' -------------- ' 行末まで読む ' -------------- Do   fs.Seek(iNowPosition, SeekOrigin.Begin)   fs.Read(aBuf, 0, 2)   aChar = ec.GetString(aBuf).Substring(0, 1)   If aChar <> Chr(13) Then     aChars &= aChar   Else     iNowPosition = iNowPosition - 1     Exit Do   End If   iNowPosition += txt.LenB(aChar) Loop While iNowPosition < fs.Length And (aChar <> Chr(13) Or aChar <> Chr(10)) しかし、実は、FGets 関数では1文字づつ読み込んでいます。 そこで、StreamReader で一行を読み込むように修正。 [イミディエイト ウインドウ] 123?????90 123?????90 123?????90 すると見事に化けてしまいました。 化けること自体は理解できるのですが、化けを修正する術がわかりません。 Function FGetl(ByVal aFile As String, _         ByVal iNowPosition As Integer, _         ByRef iNextPosition As Integer) As String   Dim aBuf(1) As Byte   Dim aChars As String = ""   iNextPosition = -1   If File.Exists(aFile) Then     Try       Using fs As FileStream = New FileStream(aFile, FileMode.Open, FileAccess.Read)         Dim sr As StreamReader         Dim ec As Encoding = Encoding.Default         fs.Seek(iNowPosition, SeekOrigin.Begin)         sr = New StreamReader(fs)         aChars = sr.ReadLine         iNowPosition += txt.LenB(aChars)         iNextPosition = NextPosition(fs, iNowPosition)         fs.Close()         Return aChars       End Using     Catch ex As IOException       MsgBox(ex.Message & "(FGets)", MsgBoxStyle.Exclamation, "エラー:")       Return ""     End Try   Else     Return ""   End If End Function 文字の化けを修正する方法を教えて頂ければ幸いです。

  • VB2005で、ファイル操作 VB6から触っていないので感覚がいまいち。

    VB2005で、ファイルを読み込み2行目から10行までを別ファイルに吐き出すコードがわからないのですが、 わかる方教えていただますか? 途中まではできたのですが、後がわかりません。 よろしくお願いいたします。 また、VB2005でわかりやすい書籍など紹介していただけましたら助かります。 'ファイルを開く Dim fs As New System.IO.FileStream(fileName, _ System.IO.FileMode.Open, System.IO.FileAccess.Read) 'ファイルを読み込むバイト型配列を作成する Dim bs(fs.Length - 1) As Byte 'ファイルの内容をすべて読み込む fs.Read(bs, 0, bs.Length) '閉じる fs.Close() ....[改行をLFとした場合に2行から10行目の内容を別のファイルに書き出すコード]

  • VBA 文字の置き換え

    下記のようなコードを実行すると置き換えはできるのですが もともとセルに入力されていた文字が消えてしまいます。 例 あいう完⇒えお完⇒かきく完 マクロ実行 かきく中 これを あいう完⇒えお完⇒かきく中 にしたいです。 よろしくお願いします。 これを Private Sub CommandButton4_Click() Dim txt As String Dim buf As String Dim buf2 As String txt = ActiveCell nStart = InStrRev(ActiveCell, "⇒") nLen = Len(ActiveCell.Text) - nStart buf = Replace(ActiveCell.Characters(Start:=nStart + 1, Length:=nLen).Text, "完", "中") ActiveCell = buf End Sub

  • VB2008

    VB初心者です、よろしくお願いいたします。 現在、VB2008を使い、顧客名簿を作成しています。 前回の質問で、テキストファイルのファイル名だけを取得する方法は分かったのですが、そのファイルの内容をテキストボックスに表示する方法がうまくいきません。 ファイルの内容は 1行目→名前 2行目→メールアドレス 3行目→郵便番号 4行目→住所 5行目→購入した商品 をそれぞれ、textbox1~5に表示させたいと思っています。 書籍などで調べた結果 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim totalcount As Integer Dim oneline As String Dim sr As System.IO.StreamReader sr = New System.IO.StreamReader("C:hogehoge\" & ComboBox1.Text & ".txt") oneline = sr.ReadLine() sr.Close() Dim skipline As Integer Dim r As Random = New Random() skipline = r.Next(totalcount) sr = New System.IO.StreamReader("C:hogehoge\" & ComboBox1.Text & ".txt") Dim i As Integer = 0 Do While i < skipline sr.ReadLine() i += 1 Loop oneline = sr.ReadLine() sr.Close() TextBox1.Text = oneline TextBox2.Text = (skipline + 1).ToString() End Sub このような記述になりました。 textbox1には問題なく名前が表示されますが、textbox2には"1"と表示されてしまいます。 すみませんが、修正箇所を教えていただけませんか? よろしくお願いいたします。

  • VB2008: クラスライブラリとはなんなのか?

    クラスライブラリとはなんなのか? 私は、クラスライブラリとはプロパティやメソッドを備えたもの。 そういう理解をしていました。 しかし、今、その認識が揺らいでいます。 それは、System.Text との出会いがきっかけ。 Imports System.IO Module mdlFileSystem   Function FileSeek(ByVal aFile As String, _ ・・・・・     If File.Exists(aFile) Then       Dim Buf(1) As Byte       Dim ec As System.Text.Encoding = System.Text.Encoding.Default       Dim fs As FileStream = New FileStream(・・・・・) これは、次のようにも書けます。 Imports System.IO Imports System.Text Module mdlFileSystem Function FileSeek(・・・・・) As String ・・・・・ If File.Exists(aFileName) Then Dim Buf(1) As Byte       Dim ec As Encoding = Encoding.Default       Dim fs As FileStream = New FileStream(・・・・・) この New 宣言を必要としない関数群とも言えるクラスライブラリ。 ここで、何が問題かと言うと実は自作の LenB関数の扱い。 Public Class Text   #Region "LenB メソッド" ・・・・・   #End Region   #Region "LenB メソッド" ・・・・・   #End Region End Class このように書くこともできます。 別にクラスライブラリなどと上段に構えなくても標準ライブラリでも用は足ります。 言わば、複数のプロパティやメソッドを装備しないのだ単なる標準ライブラリのクラスライブラリ版。 本格的なクラスライブラリ、標準ライブラリのクラスライブラリ版、標準ライブラリ。 一体、この3つをどう切り分けすべきなのであろうか? VB2008を学び始めて3週間。 しかも、プログラマでもなんでもない素人。 この辺りをどのように考えたらいいのでしょうか? どうにもスッキリしません。 「このように考えたらいいですよ」という回答をお願いします。

  • VB.NETで値や参照について ByRefなど

    VB.NETで値や参照について、まだ初学ですがよろしくお願いします。 VBは2008です。 以下のようなs文字列を参照引数にしたSetDataメソッドがあります。 ByRef s As Stringという引数は、SetData内でsを書き換えると、 呼び出したSetDataメソッド外でも中身が変わるので 私のByRefの認識ではポインタと解釈しています。間違っているでしょうか? SetData(1,1, buf)とすれば、DataGridViewの中は、「初期値」という文字が表示されます。 別のメソッド(KaKikae)でbufを"あ"という文字に変えた場合、SetDataメソッドを使わなくても 書き換わっていると思っていたのですが、実際実行してみると書き換わりません。 値や参照について理解が足りないからだと思いますがわかりません。 どのようにすれば、それが実現できるのでしょうか? Public Class HogeClass Private buf As String = "初期値" Private Sub SetData(ByVal x As Integer, ByVal y As Integer, ByRef s As String) As Boolean Dim dg As DataGridView dg = DataGridView1 dg.Item(x, y).value = s End Sub Private Sub KaKikae() buf = "あ" End Sub End Class

  • VB6.0 改行コードのないファイルの読み込み

    VB6.0で改行コードが無く、半角と全角文字が入り混じっているファイルの読み取り方法を教えて下さい。 通常の一行読み込みの範囲を大幅に超えている文字列です。 他のサイトで以下のようなプログラム(20バイトずつ切り取って読む)を見つけたのですが、 Dim InFileNo As Integer Dim Buf As string * 10 Dim LINE As Long InFileNo = FreeFile Open "C:\test.txt" For Random As #InFileNo Len = 20 LINE = 1 Do Until EOF(InFileNo) Get #InFileNo, LINE, buf LINE = LINE + 1 Loop これだと、半角と全角が混じっている箇所で文字化けを起こしてしまいます。 以上です。よろしくお願い致します。

  • vb.netでByte型の実配列サイズが大きい件

    vb.netでByte型の配列を100byteで宣言しましたが、実際の配列サイズは101byteになりました。 (例) Module Module1 Sub Main() Dim buffSize As Integer = 100 Dim inputBuff(buffSize) As Byte Dim ii As Integer = inputBuff.Length Console.WriteLine("バッファサイズ = {0}", ii) End Sub End Module ここで、iiは、101となります。 CとかC++では、有り得ない仕様ですが、どういう意味が有るのでしょうか? ご教示お願い致します。

  • VB6で特定フォルダのCSVファイルを指定して開く

     お世話になります。  ある株価を記すCSVファイルを読んで、配列格納しようと下記プログラムを書いてみましたが、 この状態では「読み込み対象のファイル」が「このVBプロジェクト」と同じフォルダに入っていなければならないようです。    そこで C:\IR_NK\USDJPY_20071010.csv の USDJPY_20071010.csv を読むというように、「別のフォルダのファイル」を読み込むように書き換えたいです。  この場合、どのように書けばいいか教えて欲しいです。 Private Sub C_FJU() Dim H_R(2) As Integer Dim HI_R(2, 8000) As String Dim intFileNo As Integer Dim strTextLine As String Dim strTxtDat As String intFileNo = FreeFile Open "USDJPY_20071010.csv" For Input As #intFileNo Do While Not EOF(intFileNo)  Input #intFileNo, strTextLine H_R(0) = H_R(0) + 1 HI_R(0, H_R(0)) = Trim(strTextLine) strTxtDat = strTxtDat & strTextLine & vbCrLf Loop T_HYO.Text = strTxtDat  Close #intFileNo End Sub

専門家に質問してみよう