アプリ版:「スタンプのみでお礼する」機能のリリースについて

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件)

最初の一行だけなら、このようにして読み込めます。



Private Sub Command1_Click()
 Dim Fname As String
 Dim iFno As Integer
 Dim i As Long
 Dim buf As String
 Dim bufbyt() As Byte
 Fname = "C:\Temp\Test1\Unknown.txt"
 iFno = FreeFile()
 Open Fname For Binary Access Read As #iFno
  bufbyt = InputB(LOF(iFno), #iFno)
 Close #iFno
 For i = 0 To UBound(bufbyt) - 1
''  buf = buf & Chr(bufbyt(i)) 'バイナリなら、この行は無意味です。
  If bufbyt(i) = 13 And bufbyt(i + 1) = 10 Then Exit For
 Next
 MsgBox i
 ReDim Preserve bufbyt(i + 1)
End Sub
    • good
    • 0
この回答へのお礼

ありがとうございます。
1.
良くわかりませんが最初の一行を読み込んでいるだけのようですが
書き込みは Print #oFno, bufbyt
でいいのですか?

2.
バイナリーの入っていない1行の文字列をD$にコピーできますか?
D$=buf

3.
読み込むファイルは何千行もあるのですが
バイナリーのある行は予測できるのですが
その場合はLine Input D$
でなくてどのようにしたらいいのでしょうか?

お礼日時:2016/08/30 22:38

直接的な回答ではないのですが、


ファイルをコピーするのであれば、
FileCopy で可能かと思いますが、それではだめなのでしょうか?
特別に1行単位で処理しなければいけない理由があるのでしょうか?
    • good
    • 0
この回答へのお礼

だめです。
基本的に1行ずつ読み込みます。
ある部分では十数行読み込んで解析してある部分を別の文字列に変換して
そのまとまりを一気に書き込みます。
このような動作は何千から何万もあります。

お礼日時:2016/08/31 20:48

ファイルをコピーするだけなら、「1行」なんて「面倒くさい」区切りで考える必要なく


GETでバイナリデータを読み込んで、PUTでバイナリデータを書き出す、でいいのでは?
    • good
    • 0
この回答へのお礼

バイナリーで読み込むとしてそれを
1行分を文字列配列の中にコピー次々にコピーできますか?

お礼日時:2016/08/31 20:50

#1の回答者です。


もう一度読みなおしてみました。
>1行のなかに0000から0020までのコントロールコード

なぜ、バイナリか、よく読んでいなかったけれど、通称、エスケープシーケンスではありませんか?その中でCRLF だけを残すわけでしょう?昔は、よくあった話ですが、今は、ほとんど聞かれなくなってしまいましたね。

実務的なことなのですが、私の場合は、いつだったか、あまり頭を使ってもうまくいかないので、NotePad++ で、処理したことを思い出しました。これって、目からうろこです。
巨大なファイルだったので、コマンドライン系のツールでも、できないものも出てきました。

>読み込むファイルは何千行もあるのですが
いろいろあれこれやっていたのに、あっという間です。NotePad++ の正規表現置換で、たぶん希望通りのことは可能です。

[\x00-\x20]

これでなぜ、CRLF が残るのかはよく分かりません。含まれているはずなのですが、素通りしていくようです。急ぎなら、こうしたほうがよいと思います。

ちなみに、先ほど、nkf でできると思ってやってみましたが、nkf やnkfwin でも、うまくいく様子がありません。もし、nkf でできれば、VB6 に組み込めばよいのですが。何が原因か、まだ分かりません。
    • good
    • 0
この回答へのお礼

0
TEXT
5
609A7
330
18
100
AcDbEntity
8
0
100
AcDbText
10
-0.0095238095238095
20
-0.2
30
0.0
40
2.5
1
ABC
100
AcDbText
0

このような組み合わせが何千何万もあります。

の中で  1の後のABCが文字列ですがバイナリーが含まれているとおもいますが
Line Input #1,DAT$
で読み込めません。

お礼日時:2016/08/31 21:42

> ある部分では十数行読み込んで解析してある部分を別の文字列に変換して


> そのまとまりを一気に書き込みます。

そのような変換があるものを「コピー」とは言いません。

> ただ1行のなかに0000から0020までのコントロールコードが入っていところが所々あります。

本当に、その範囲ですか?どうやって確認しましたか?

> 1の後のABCが文字列ですがバイナリーが含まれているとおもいます

と言われても、こちらでは確認のしようがありません。
・テキストエディタだと、該当箇所はどんな文字列になっているのか?
・バイナリエディタだと、該当箇所はどんなコードになっているのか?
・Line Input したときの文字列の、該当箇所のコードはどうなっているのか?(Asc関数で調べる)

どうしてうまくいかないのか?どのようにうまくいかないのか? が判明しないことには、プログラムの方針も決まりません。

・VB6のStringは内部でUnicodeを使っている
・Line Input すると、 ファイルをShift_JISと解釈して、 ファイルのShift_JISデータ→文字列変数のUnicode という変換が行われる
となっていて、入力ファイルがUTF-8で書かれているために、文字化けしたものが取り込まれている、という状況も考えられます。



Visual Basic 6 での開発をやめる、という選択肢もあります。
    • good
    • 0
この回答へのお礼

ありがとうございます。
表現が適切ではなくすいません。1の後に文字列が入るのですが
ABCの場合はたとえばの例であって実際は様々な文字列が入ります。
その文字列のところで、AutoCADで読み込むときにエラーになります。
元々の文字列はテキストエディターで見てみますと別の文字列になって新しいファイルにコピーされているので
バイナリーかなと思っていました。

VB6ではだめなんですね?
Visual Basic 2010は持っていますが購入しただけで一度も使ったことはないのですが
コードを書き直す必要があって書き直せば私の意図通りに動作するものでしょうか?

Visual Basic 2008は先日ダウンロードしてコードを読み込むと
自動変換されましたが3か所エラーがでました。

お礼日時:2016/09/01 08:04

>VB6ではだめなんですね?


私は、そういう問題ではないと思っていますね。
VB6で、あらゆる文字コードを扱うプログラミングをする人もいるわけですから。

でも、今回は、もう歯が立たないというか、ぜんぜん分野の違うところで、そういう技術は、今のところ私にはありませんでした。

#4のお礼欄で、やっとわけが分かりました。まず、おっしゃっているのは、『DXFコード』のようですね。私の書いていた内容は、バカみいたです。(;_;)#1の延長上で、バイナリは落とすことはたぶん可能だと思いますが。

AutoCAD 2011 ヘルプ
http://docs.autodesk.com/ACD/2011/JPN/filesDXF/W …

DXF形式の「タグ付きデータ」は、ファイル内の各データ要素の前に、「グループ コード」と呼ばれる整数が付いたデータのことだそうですね。
今、サンプルコードを拾ってクリックしたら、LibreOffice のDraw が開きました。
このファイルには二種類あるようで、アスキータイプとバイナリタイプとがあり、今回は、後者のようですが、サポートしているシステムもほとんどないと書かれていましたが、実際は知りません。

http://docs.autodesk.com/ACD/2014/JPN/index.html …

ご自分で作ることは悪いとは思わないけれども、バイナリDXF だとしたら、ちょっとやそっと触れさせないと違いませんでしょうか。

DXFファイルの読み込み入門(第1回)
http://siren.xyz/2016/03/06/dxf%E3%83%95%E3%82%A …

ツール
VoiCeFREE
http://www.vector.co.jp/soft/winnt/business/se34 …

Autodesk DWG TrueView
http://autodesk-dwg-trueview.softonic.jp/

さて、これから、どうしたら良いでしょうかね。
今のファイルが、Autodesc などで読めない、というか、純粋なテキストファイル(たぶん、sjis ファイル)にするということをするなら、また考えなくてはなりません。

また、テキストファイルはずなのに、バイナリが入っているというのは、元の出力装置側の信号だと思います。やってみないと分かりませんが、思い当たる節があります。サンプルファイルがあれば、それに越したことがありませんが。
    • good
    • 0
この回答へのお礼

ありがとうございます。
当方DXFに関する書籍はすべて所持しております。
私が取り扱うとするDXFはバイナリーかテキストかといえば
テキストに分類されるはずです。
VisualBASIC 6.0のLine Inputで読み取ったデータをそのまま書き込むと文字列が変わってきます。
このことが不思議です。たぶんバイナリというのは想像の域から脱していません。

お礼日時:2016/09/01 19:44

想像なんてどうでもいいです。



正しい情報をください。
間違った情報から、正しい結論を導くのは無理です。


(1)複数の文字コードに対応したテキストエディタで、元のファイルを開いてください。
 例) サクラエディタ

(1-1) 日本語が正しく表示されているか、確認してください。
 そのとき、文字コードがどうなっているか調べてください
 例) サクラエディタの場合、ウィンドウ下のステータスバーに表示される

(2) 元ファイルをバイナリエディタで開いてください。
 例) BZ http://forest.watch.impress.co.jp/library/softwa …

(2-1)文字数や周辺の文字列を参考に、1-1で確認した日本語の場所を探して、それに続く10バイトくらいの内容を確認してください。
 改行1改行 なら 0D 0A 31 0D 0A というバイト列の直後になっているはずです。
 また、その中に、あなたの言う「0000から0020までのコントロールコード」は入っているかどうか、よく確認してください。

確認して、本当にコントロールコードだったらそのときに考えればいいことです。



おそらく、元のファイルがUTF-8で書かれているのでは?

VB6では、 文字コードをShift_JISだとして解釈して読み込むので、あなたが「読み取ったデータをそのまま書き込」んだつもりでも、
実際には、UTF-8ファイルを読んだ時点で文字化け→文字化けのままファイルに書き込み、となっていると思われます。

半角英数は、UTF-8でもShift_JISでも同じなので、漢字や仮名が使われているところだけ文字化けします。


VB6でもできないわけではありません。
・LineInput 相当の Byte配列を を返す関数を自作して、LineINputの代わりに使う。
 StrConvで 特定の文字コードのByte列→Sting に変換できる
 書くときは、StrConvで逆変換
・FileSystemObject等の、外部の力を借りる

ですが、それが面倒なら
・VB6より簡単にできるプログラミング言語を使う
のも手かと。
この回答への補足あり
    • good
    • 0
この回答へのお礼

ありがとうございます。
ものすごく感謝しています。
早速調べてみます。

お礼日時:2016/09/01 22:38

こんにちは。



私は、先走って回答を用意して、的が外れていました。昔の経験や知識と混ぜあわせになって、まったく見当はずれの回答をしようとした自分が、つくづく、嫌になってしまいます。

そのバイナリ・コードをみたら、いくら私でも分かったのですが、何か話が断片的でしたから、違ったところばかり見ていました。

それとプログラム的にどうとかこうとかいう話とは別に、#4で私の言っていたNotePad++ を使えば、もうとうにわかったことです。知る人ぞ知る最高のツールです。国産で匹敵するものは見たことがありません。以下のようなプログラム的解決はせずに済むのです。nkf やgrep などの古いUnix変換ツールなど匹敵にならないほどの大変な万能ツールです。

別に、この先、どういう思惑で進むのかは、私には分かりませんが、誰でも知っているコードを書くというのも顰蹙モノですが、ちょっと書き込みを残しておきます。

'//
Sub ConvertText()
'UTF-8 をShift JISに変換
Dim objSrc As Object  'ADODB.Stream
Dim objDst As Object ' ADODB.Stream
Dim iFName As String
Dim oFName As String
iFName ="C:\Temp\Test1\TestUT8.txt" ' import
oFName ="C:\Temp\Test1\TestS_JIS.txt" 'output
 Set objSrc = CreateObject("ADODB.Stream")
  With objSrc
    .Type = 2 ' adTypeText
    .Open
    .Charset = "UTF-8"
    .LoadFromFile iFName
    .Position = 0
  End With
  Set objDst = CreateObject("ADODB.Stream")
  With objDst
    .Type = 2
    .Open
    .Charset = "Shift_JIS"
    .Type = 2 'adTypeText
  End With
  objSrc.CopyTo objDst
  objDst.Position = 0
  objDst.SaveToFile oFName, 2
  Beep
End Sub
    • good
    • 0
この回答へのお礼

すいません。私の質問の方法が悪かったことが元々の原因です。
気になさらないでください。
コードありがとうございます。大大大、感謝します。

お礼日時:2016/09/02 15:35

念の為、正しいか検証してみましょう。



元の
EF BC B4 / EF BC 8E / EF BC AB
がUTF-8で
T.K

これをShift_JISとして解釈すると
EF BC →存在しない文字→「・」(Shift_JISで 81 45)に置き換え
B4→半角カタカナ「エ」
EF BC →存在しない文字→「・」に置き換え
8E EF →「趣」
BC→シ
AB→ォ

辻褄合いますね
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2016/09/02 22:14

バイナリーデータを読み込み、CR(0x0D),LF(0x0A)までを1行として切り出すようにしました。


又、切り出した1行をバイナリーデータとして書き込む機能も設けました。

提示したソースでは、
myBinayCopyに入力ファイルと出力ファイルを指定すると、
入力ファイルから1行単位でデータを取得し、それを出力ファイルに出力しています。
読み込んだ1行を加工するということですので、
myBinayCopyをあなたの要件に従い、加工すれば、使えるようになるかと思います。

以下の関数を使用してください。
入力ファイルのオープン:myReadOpen
出力ファイルのオープン:myWriteOpen
ファイルのクローズ:CloseHandle(Windows API)
入力ファイルから1行の取得:myGetLine
出力ファイルへ1行分データの書き込み:myPutData(1行でなくても良い)

上記以外は、特に使用することはないはずです。

Visual Basic 6.0で提供されているInput関数はバイナリーモードで読み込んだ場合、
詳細の説明は割愛しますが、今回のようなケースでは期待した結果を(仕様上)返してくれません。
その為、Windows APIのReadFile,WriteFileを直接呼び出して、読み書きを行うようにしました。

途中で、処理内容がわかるようにするため、msgBoxで内容を表示していますが、
不要であればコメントアウトしてください。
又、ファイルの読み書きで、エラーチェックは多少端折っていますが、実用上は問題ないと思います。
厳密な意味でのエラーチェックを望まれる場合は、そのように書き換えてください。

処理結果として
入力ファイルと出力ファイルが完全に一致すること
入力ファイルの行数を正しくカウントしていること
入力&出力ファイルのファイルサイズが正しくカウントされていること
を確認済みです。
(Windows7のXPモードでvb6を実行して確認)

尚、以下のような入力ファイルは、エラーとしています。
1行の終端にCR,LFが存在しない。(1行は最大32768バイト)
ファイルの終端がCR,LFで終わっていない。

ソースは、文字数がオーバーするので、次のNoで投稿します。
    • good
    • 0
この回答へのお礼

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

BASICでC使えるの??

お礼日時:2016/09/03 18:45

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