プロが教える店舗&オフィスのセキュリティ対策術

Visual Basic 6.0で ファイルをコピーするソフトを作っています。
ただ1行のなかに0000から0020までのコントロールコードが入っていところが所々あります。

だからその行にはLine Input では正確に読み込めません。
書き込むと違う文字になっています。

char = Input (1, #1)
char = inputB(1, #1)

でバイナリが含まれている1行だけ読み込みみたいのですが
0D 0A
すなわち CR LF
まで読み込むにはどうしたら良いのでしょうか?

この文章の意味がわかる方お願いします。

質問者からの補足コメント

  • >UTF-8ファイルを読んだ時点で文字化け→文字化けのままファイルに書き込み、となっていると思われます。
    確かにその通りでした。
    http://homepage1.nifty.com/cadconv/kaiseki.xls
    正確にアップロードできないのです。理由はわかりません。
    \W0.781;\Q+8.00;\A1;2

    \W0.781;\Q+8.00;\A1;・・
    になっていました。

    すなわち
    5C 57 30 2E 38 33 33 3B 5C 41 31 3B EF BC B4 EF BC 8E EF BC AB 0D 0A

    5C 57 30 2E 38 33 33 3B 5C 41 31 3B 81 45 B4 81 45 8E EF BC AB 0D 0A
    になっていました。

    No.7の回答に寄せられた補足コメントです。 補足日時:2016/09/02 09:47
  • 実際は漢字コードは新たに作るファイルにそっくりそのままコピーできればいいんです。
    内容がどうでも構わない。

    変換したいことは
    1.ファイルの中のある範囲内で以下の文字を変換したい。
    __6
    の後の1行の文字列に従って
    __8
    の後の1行の文字列が変換できればいいのです。

    2.その他の文字列は正確に1行1行正確にコピーできれば良い。
    以上

    _は実際は半角スペース 0x20です。

      補足日時:2016/09/02 21:23

A 回答 (22件中1~10件)

前回提示したソースはバイナリーモードで扱っているため、取得した1行がbyte型になります。


この状態であなたのソースに組み込むのは、非常に労力を要しますし、また組み込めたとしても、
非常に分かりずらくなるため、ほかの人が担当になったとき、非常にこまるかと思います。
今回はutf8(BOM無)のテキストファイルであることが判明しているため、
VB6でutfのテキストファイルの読み書きをするという観点で考え直したほうが良いと思います。
前のソースはすべて忘れてください。
以下のサイトにVB6でutf8ファイルを読み込み、1行単位で出力用ファイルに書き込むプログラムを
新たに投稿しました。
http://climbi.com/b/7779/0


以下のサイトを参考に作ってあります。
http://d.hatena.ne.jp/niemands/20090316/1237225383
http://amano41.hateblo.jp/entry/2014/04/25/145637

尚、このソースを動作させる場合は、
参照設定でMicrosoft ActiveX Data Objects x.x Libraryにチェックを入れておく必要があります。
(こちらでvb6で確認時はx.x=2.8でした)

このソースをMODULE2.BAS などに作成してください。
例によって、
Public Sub myCopyFile(ByVal infile As String, ByVal outFile As String)がありますので
call myCopyFile(inFile,outFile)
とすると、inFileの内容をoutFileに書き出しています。
又、1行の内容が"ENTITIES"の場合、その内容と行番号を表示しています。
実行後、inFileの内容とoutFileの内容が全く同じになりますのでそれを確認してください。

実際にこれをあなたのプログラムに組み込む場合は、以下の点に留意してください。
(1)今回ADODB.Streamをしているが、utf8のテキストファイルを出力すると、
BOMが付加されてしまう。
(BOMとはデータの並びを示す為の3バイトの情報で、ファイルの先頭に存在します。)
今回のデータはBOM無なので、コピーするときも出力ファイルはBOMなしにする必要があります。
そのため、出力用ストリームの4バイト目以降を別の出力用ストリームにコピーし
それを出力用ファイルに出力しています。
このことをまず、記憶しておいてください。

(2)あなたのソースとこちらで提示したソースは、以下のように対応します。
左側があなたのソース、右側が私が提示したソースです。
入力ファイル識別子 inFn% <=> txt
1行入力したデータ gdata$ <=> gdat$
出力ファイル識別子 outFn% <=> txt2,txt3
(基本的にはoutFn%とtxt2が対応する。但し、ファイルへ出力するのはtxt3)

1行の読み込み Line Input #inFn%, gdat$ <=>  gdat$ = txt.ReadText(adReadLine)

1行の書き込み Print #outFn%, gdat$ <=> txt2.WriteText gdat$, adWriteLine

修正オブジェクトデータ出力 Print #outFn%, Object$(k%)
これは、こちらのソースにはありませんが
txt2.WriteText Object$(k%), adWriteLine
でいけるはずです。

入力ファイルを全て読み終わった後に、txt2の内容を(先頭3バイトを除いて)txt3にコピー
することを忘れないでください。(この処理を行わないとBOM付きのファイルになります)
不明点があれば、補足してください。
    • good
    • 1

こんにちは。



WindFaller です。もし、読んでいたら、教えていただきたいのですが、この件の問題は、UTF-8 では、エラーが発生してしまうファイルを、おそらく、SJISで変換して、

>最終的には、DXF ファイルが、CAD で、読めれば

ではなかつたのはないでしょうか。バイナリーのことばかりが目に言っていましたが、それ以上に、変えようもないと思った次第です。

良くある、BOMなしUTFファイルの場合に起こるトラブルのような気がしたのですが、まったく見当はずれの意見なら、お許し下さい。最終的な落ち着き場所がみえていなかったのです。
    • good
    • 0

#20です。


一点、誤りがありました。
誤:1行入力したデータ gdata$ <=> gdat$
正:1行入力したデータ gdat$ <=> gdat$
となります。訂正いたします。
    • good
    • 0

>rHandleが文字列半角”  2”と同じかどうかはどのようにしたらいいのでしょうか?


>1行読み込んでその文字列が”ENTITIES"だったら
>”  0”までは
>O$(5000)にカッコ内1から順次コピーしたいのですが・・・。

何をなさりたいのかがよくわかりませんので、要件を確認いたします。

(1) これは1行が以下のように構成されているということですか?
任意の文字列+"ENTITIES"+任意の文字列+"□□0"+任意の文字列
(□は半角スペース)

(2) もし、任意の文字列+"ENTITIES"の後に"□□0"が存在しないなら、コピー対象外にして良いですか。

(3) O$にコピーしたいということですが、これは変換後の文字列を書き込む為のものでしょうか。
この型は、string型になりますが、byte型でなければいけません。
Dim buff2(BUFF_SIZE-1) as byte と定義し、buff2を変換後の文字列を書き込むバッファとしますが良いですか。
(BUFF_SIZEの値は32768です)

(4) buff2に(1)で読み込んだ1行を
任意の文字列+"ENTITIES"+任意の文字列+"□□0" 迄コピーします。

(5) その後、どのようになさりたいのでしょうか?
ここから先がよくわかりませんが、もし、このbuff2に更にCR,LFを付加して出力ファイルに書き込む
ところまでの、例がほしいということであれば、その例を提示することは可能です。
まず、上記の要件が正しいかどうか、確認していただけませんでしょうか?
    • good
    • 0
この回答へのお礼

いつもありがとうございます。
コピーはうまくいきました。
感謝です。

http://homepage1.nifty.com/cadconv/ORG-1-YK.dxf
です。
ENTITIES
__0
から
__0
までが一つのまとまりです。

以下のソフトで半角アルファベットや数字ならですが一様動きます。
utf-8が入っているとエラーになります。
http://homepage1.nifty.com/cadconv/FrmDxfLayerCH …
あなた様のソフトと組み合わせることはどうしたらいいのかがいまいちわかりません。
すいません。
以上

お礼日時:2016/09/05 16:41

>(2)の前に


>wHandle = rHandle
>を記述してもABC-Copy.txtにコピーされません。
>line_no=0
>file_size=0
>となります。
>rHandleが文字列半角”  2”と同じかどうかはどのようにしたらいいのでしょうか?
>1行読み込んでその文字列が”ENTITIES"だったら
>”  0”までは
>O$(5000)にカッコ内1から順次コピーしたいのですが・・・。

wHandle = rHandle このようなことをしてはいけません。
rHandleには入力ファイルのファイル番号(1,2,3等の整数)が格納されています。
wHandleには出力ファイルのファイル番号(1,2,3等の整数)が格納されています。

読み込んだ内容はbyte型の配列のbuffに格納されています。
buffの中が”ENTITIES"かどうかを判定してください。

尚、問題点をクリアするために、
myBinayCopyの中は一切変更せずに

Call myBinayCopy(inFile, outFile)
を行って、utf-8のファイルがinFileからoutFileにコピーされることを確認されてはいかがでしょうか。
    • good
    • 0

#16です。


もう、一点追加です。
myBinayCopy(inFile, outFile) でなく
Call myBinayCopy(inFile, outFile) としてください。(Callを付加してください)
    • good
    • 0
この回答へのお礼

大変お世話になっています。
(2)の前に
wHandle = rHandle
を記述してもABC-Copy.txtにコピーされません。
line_no=0
file_size=0
となります。

rHandleが文字列半角”  2”と同じかどうかはどのようにしたらいいのでしょうか?

1行読み込んでその文字列が”ENTITIES"だったら
”  0”までは
O$(5000)にカッコ内1から順次コピーしたいのですが・・・。

お礼日時:2016/09/04 12:30

>Form1.frmの


>Private Sub Command1_Click()
>inFile = "ABC.txt"
>outFile = "ABC-Copy.txt"
>myBinayCopy(inFile, outFile)
>End Sub
>コンパイルエラー
>構文エラー
>で動きませんが?

エラーメッセージはどのようになっていますか?
inFileは Dim inFile as string のように定義していますか。(outFileも同様)

ファイル名は完全パスで指定してください。
"ABC.txt" でなく "c:\xxx\yyy\ABC.txt"のように指定してください。
c:\xxx\yyyは実在するフォルダです。あなたの環境にあわせてフォルダ名を指定してください。
    • good
    • 0

>form1.basに書き込むのですか?


>ファイルのオープンすることからわかりません。

https://support.microsoft.com/ja-jp/kb/165942
のサイトでは、
1.新規の標準 EXE プロジェクトを作成し、MODULE1.BAS を追加します。
2.MODULE1.BAS に次のコードを入力します。
となってます。

MODULE1.BASに書き込んでください。

最初に見るのは、
Public Sub myBinayCopy(ByVal inFile As String, ByVal outFile As String)
です。
myBinayCopy(入力ファイル名,出力ファイル名)を
他から(form1.bas等)から、呼び出せば、入力ファイルを1行単位で読み込み、1行単位で出力ファイルへ書き込んでくれます。
しかしながら、あなたが望む要件に従えば、1行単位で読み込んだ後、何がしかの変更を行い、それを1行単位で、書き込むことになります。
その為、myBinayCopyの中をあなたが改造する必要になります。(他のプロシージャは一切変える必要はありません)
myBinayCopyは、
Public Sub myBinayCopy(ByVal inFile As String, ByVal outFile As String)
Dim rHandle As Long
Dim wHandle As Long
Dim buff(BUFF_SIZE - 1) As Byte
Dim buff_len As Long
Dim flag As Boolean
Dim fSuccess As Long
Dim line_no As Long
Dim file_size As Long
MsgBox ("<" & inFile & ">" & vbCrLf & "<" & outFile & ">")
line_no = 0
file_size = 0
rHandle = myReadOpen(inFile)
If rHandle = INVALID_HANDLE_VALUE Then
Exit Sub
End If
wHandle = myWriteOpen(outFile)
If wHandle = INVALID_HANDLE_VALUE Then
Exit Sub
End If
flag = True
Do
buff_len = myGetLine(rHandle, buff)・・・・・・・・・・・(1)
If buff_len > 0 Then
line_no = line_no + 1
file_size = file_size + buff_len
fSuccess = myPutData(wHandle, buff(0), buff_len)・・・・(2)
Else
flag = False
End If
Loop While flag = True
CloseHandle (wHandle)
CloseHandle (rHandle)
MsgBox ("line_no=" & line_no)
MsgBox ("file_size=" & file_size)
End Sub

となってますが、
(1)で1行読み込んだ内容が、buffに格納されます。(1行の長さはbuff_lenで示されます)
(2)で1行書き込みますが、その前にbuffの内容をあなたの要件に従い、変更します。
その時、(2)で書く場合、この例では単純コピーなのでbuffとbuff_lenを指定していますが、同じものを指定する必要はありません。buff2とbuff2_len等を別途設け、それを指定してもかまいません。
(buffの内容を変換し、1行の長さが変わらなければbuffをそのまま使用できますが、buffの長さも変わるなら
別途、buff2とbuff2_lenを出力用に設け、それを指定したほうがよいでしょう)

myBinayCopy以外のメソッドは使い方さえわかればとりあえずは問題ありません。
一応、パラメータもコメントに書いてあるので、使い方はわかると思いますが、不明点があれば補足してください。
    • good
    • 0
この回答へのお礼

感謝します。たびたびすいません。

上記コードはForm1.frmに書くのですね。
また、MODULE1.BASは 標準モジュールの追加 をしました。

Form1.frmの
Private Sub Command1_Click()
inFile = "ABC.txt"
outFile = "ABC-Copy.txt"
myBinayCopy(inFile, outFile)
End Sub

コンパイルエラー
構文エラー

で動きませんが?

お礼日時:2016/09/04 10:50

#10です。


>ここまでして大変
>大変いいにくいのですがバイナリーというより
>文字列がS-JISではなくUTF-8ということで
>文字列を読み込めないことが発覚しました。
>すなわちLine Input #iFn,D$
>で読み込んだデータが文字化けして
>Print #oFn,D$
>で書き込んでいることがわかりました。

なるほど、そういう事情であればUTF-8に特化したテキストファイルの読み書き方法があるかもしれませんね。
私が提示したソースはUTF-8で作成されたファイルでも問題なく動作することが確認済みですので、
ほかに打つ手がない場合は、私のソースを参考にしてください。
コピー&ペーストすれば、そのまま使えます。(単純な1行単位のコピーですが)
    • good
    • 0

#10です。


ありがとうございます。
でも、 全く言っていること 全くわかりません。
myReadOpen 何これ
myWriteOpen なにこれ
CloseHandle え?
myGetLine Cじゃないの????????
myPutData C#? D?

VB6(Visual Basic 6.0)でつかえますよ。
実際に動作確認をした旨もかいてあります。
(VB6自体がwindows7で動作するかどうかは不明でしたので、windows7のXPモードでVB6を動作させています)
くどいようですが、ソースは、VB6です。
https://support.microsoft.com/ja-jp/kb/165942
にVB6でバイナリーファイルのアクセス方法がかいてあります。
まず、ここを参照してください。
    • good
    • 0
この回答へのお礼

どうもいろいろありがとうございます。
大感動。大感謝です。
ここまでして大変
大変いいにくいのですがバイナリーというより
文字列がS-JISではなくUTF-8ということで
文字列を読み込めないことが発覚しました。
すなわちLine Input #iFn,D$
で読み込んだデータが文字化けして
Print #oFn,D$
で書き込んでいることがわかりました。
ごめんなさいね。
もちろんコードは研究します。

お礼日時:2016/09/03 21:04

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