C言語関係掲示板

過去ログ

No803 テキストストリームとバイナリストリーム

[戻る] [ホームページ]
No.10071

10(MS-DOS)
投稿者---ceybord(2003/10/26 23:06:16)


ちょっと疑問に思ったのですが、
putchar(10)とかprintf("\n")とかはDOS用のコンパイラで作った実行ファイルを実行するとちゃんと(?)改行で出ますが、
モード"wb"で開いたファイルにデータを書き込むときコード0Aを
0D0Aを間違って書いてしまうことって(まともなコンパイラなら)絶対にありえないことですか?
もうひとつ、DOS用コンパイラで作ったファイルを実行したとき、テキストモードで開いたファイルから改行コード0D0Aを読み出すときには、どのような形式で読み出しているのですか?0D0Aになるのですか?それとも0Aになるのですか?

No.10073

Re:10(MS-DOS)
投稿者---YuO(2003/10/26 23:25:48)


>putchar(10)とかprintf("\n")とかはDOS用のコンパイラで作った実行ファイルを実行するとちゃんと(?)改行で出ますが、
>モード"wb"で開いたファイルにデータを書き込むときコード0Aを
>0D0Aを間違って書いてしまうことって(まともなコンパイラなら)絶対にありえないことですか?

最低でも,C90規格に適合しているコンパイラであれば,
そのようなことは許されません。


>もうひとつ、DOS用コンパイラで作ったファイルを実行したとき、
>テキストモードで開いたファイルから改行コード0D0Aを読み出すときには、
>どのような形式で読み出しているのですか?

どのような形式とは?
MS-DOS Function Requestの読み出し機能(INT 21H / AH=3FH)を利用した場合,
0Dh 0Ahは別々に読み出されますが。
FCBを使った場合(INT 21H / AH=14Hor21H)でも同じことです。


No.10082

Re:Re:10(MS-DOS)
投稿者---ceybord(2003/10/27 09:56:33)


>MS-DOS Function Requestの読み出し機能(INT 21H / AH=3FH)を利用した場合,
>0Dh 0Ahは別々に読み出されますが。
>FCBを使った場合(INT 21H / AH=14Hor21H)でも同じことです。

それでは、読み出しのときのテキストモードとバイナリモードの違いがよくわからないのですが、DOS用コンパイラでは"r"と"rb"はどう違うのですか?

No.10087

Re:Re:10(MS-DOS)
投稿者---YuO(2003/10/27 12:46:35)


>それでは、読み出しのときのテキストモードとバイナリモードの違いがよくわからないのですが、
>DOS用コンパイラでは"r"と"rb"はどう違うのですか?

テキストモードはライブラリレベルでの話ですから,MS-DOS Function Requestによって得られたバイナリの値で,
0Dh 0Ahの並びを見つけた場合,テキストモードで開かれたファイルのときのみ,0Ah一文字に置き換えます。

このあたりの事情はWindows用のライブラリでも同じ話です。
ReadFile APIや_lread APIを使って実際にディスクから読み込む処理は完全にバイナリです。
それを,fgetcが読み込む時点(またはキャッシュする時点)で,置き換えを行います。


No.10095

Re:Re:Re:10(MS-DOS)
投稿者---ceybord(2003/10/27 20:25:27)


よくわかりました。
それではUnixのように改行を0Aひとつで扱っているOS上のCコンパイラを使う場合は、オープンモード"w"と"wb","r"と"rb"はどこか違うのですか?

No.10098

Re:Re:Re:10(MS-DOS)
投稿者---YuO(2003/10/27 21:24:10)


>それではUnixのように改行を0Aひとつで扱っているOS上のCコンパイラを使う場合は、
>オープンモード"w"と"wb","r"と"rb"はどこか違うのですか?

違うかもしれないですし,違わないかもしれません。
どのように違うかは,処理系に依存します。

テキストストリームについて,標準(ISO/IEC 9899:1999)は次のように言っています。
  • 次の条件を満たす場合のみ,読み込んだデータは以前にテキストストリームに書き込んだデータと一致する必要がある。
    • データが表示可能な文字及び水平タブと改行文字のみからなる。
    • 改行の前に空白文字が無い。
    • 最後の文字が改行文字である。
  • 改行の直前の空白文字を読み込むかどうかは実装定義である。
  • 最終行の末尾に改行が必要かどうかは実装定義である。
  • 最低でも254文字を収容する行をサポートする必要がある。

また,バイナリストリームについては,次のように言っています。
  • 同一の実装下において,読み込んだデータは以前にバイナリストリームに書き込んだデータと一致する必要がある。
  • ストリームの末尾に実装定義の個数のナル文字を追加できる。

でもって,脚注223で,テキストストリームとバイナリストリームを区別する必要はない,と言っています。
#脚注は標準ではないですが。


とりあえず,人にあれこれ聞くよりも自分で標準を調べた方がよいと思います。
JSA Web Store
ANSI Electronic Standards Store


なお,JIS X 3010は書籍をお薦めします。
PDFで買っても,イメージベースなので検索できない上に大きいですし,
書籍からスキャンしたので文字が消えかけていたりします。
#JIS X 3010はPDFでも書籍でも値段は変わりません。


No.10105

Re:Re:Re:Re:10(MS-DOS)
投稿者---ceybord(2003/10/27 22:50:29)


Unixでは、結局オープンモードのテキストモードとバイナリモードの区別は曖昧になるのですね。
それにしても改行コードの統一性のなさはこれからも波紋を呼びそうです。
それに限らず、7ビットコードは全てのシステムで統一して欲しいものです。
いろいろとありがとうございました。

No.10135

Re:Re:Re:Re:10(MS-DOS)
投稿者---YuO(2003/10/28 23:33:59)


>Unixでは、結局オープンモードのテキストモードとバイナリモードの区別は曖昧になるのですね。

ちゃんと読みました?
私が書いた結論は,#10098における引用でない文の2行目に凝縮されていますが。

テキストとバイナリを区別するか否かは処理系に任されているのであって,
OSに任されているわけではないです。
そこのところはちゃんとわかっていますか?


>それにしても改行コードの統一性のなさはこれからも波紋を呼びそうです。

どこで波紋を呼ぶのですか?

ISO/IEC 6429を使うとして,まともなエディタならCR/LF/CRLFすべてに対応しているでしょうし,
対応していないプログラムでも,通す前に変換フィルタに一回通せばよいわけです。

さらに,ネットワークに関してもMIME-typeが関連する転送方式(SMTPやHTTPなど)では,
text/*の改行はCRLFと定められています(RFC 2046)。

ISO/IEC 6429を使っていないファイルを使っているシステムで扱うなら,
たぶん符号化方式の変換を行ってやる必要があります。
#文字集合間での転写も必要になるかもしれません。
その時点で,システムに適した改行コードに変換できるのだから問題はないです。


>それに限らず、7ビットコードは全てのシステムで統一して欲しいものです。

どの文字集合と符号化方式を選択するのですか?

ISO 646/IRVにしますか?
そうすると,JIS X 0201+JIS X 0208をShift_JISを利用するマシンでは,
REVERSE SOLIDUSが使えないから毎回Trigraphを使って??/と書くんですね。
さらに,TILDEも使えないから??-ですね。
#REVERSE SOLIDUSとYEN SIGN, TILDEとOVERLINEは当然別の文字です。

EBCDICにしますか?
そうすると,ISO 646を元にしたコードを使っているマシンでは,
fputcのたびに文字コードの変換ですね。
#当然逆もありうる。


No.10139

Re:Re:Re:Re:Re:10(MS-DOS)
投稿者---InitialC(2003/10/29 12:25:03)


日本語文字コードはEUCを採用すればいいのです。
全角文字(および半角カナ)はA1からFEまでしか使わず、経済的です。
7bitコードの統一は現時点ではかなり困難を極めそうです。