質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

6回答

1425閲覧

<C言語>テキストストリーム・バイナリストリームの定義

cadet_study

総合スコア13

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

4グッド

4クリップ

投稿2018/09/03 12:56

標準C言語のストリームの定義の解釈の仕方が分からない…

こんばんは。初歩的な内容で大変申し訳ないのですが質問させていただきます。
テキストファイル・バイナリファイルについて学習をしていたところ、標準C言語のテキストストリーム・バイナリストリームについての定義を見つけたのですが、その定義部分についてよくわからない部分があります。

###テキストストリーム・バイナリストリームの定義(分からなかった点を抜粋)

私が学習に使用しているテキストには、テキストストリームについての定義がつぎのように表記されていました。

<テキストストリーム>

➀「行」を構成する,一連の順序付けられた文字の並びである。
各行は、0個以上の文字に、行の終端を表す改行文字を付加したもので、テキストストリームの最終行が、終端を表す改行文字を必要とするかどうかは処理系定義である。

➁ホスト環境内でテキストを表現するための規約に適合させるために、入力と出力の際に文字を変更・付加・削除しても良い。

➂テキストストリームから読み取られるデータが、そのストリームに書き込まれたデータと比較して一致することが保証されるのは、次の条件を満たす場合に限られる。

・データが表示文字と水平タブ,改行文字のみで構成される。
・改行文字の直前に空白文字がない。
・最後の文字が改行文字である。

etc...

<バイナリストリーム>

・バイナリストリームから読み取られるデータは、同一の処理系のもとでは、以前にそのストリームに書き込まれたデータと比較して一致しなければならない。

etc...

自分の解釈・疑問点

1:fputc() や fgetc() のように、1つの文字をテキストストリームに読み書させる際は、ストリームの➀の定義に外れることになるのでしょうか?(外れるとしたらどうなるのですか…)

2:➁の定義における3つの規則は、読み込まれるとき・書き込まれるときのテキストストリーム上のデータの状態を指し、読み込み・書き込みの際の両方でストリームのデータがその条件を満たしていなければならない,ということなのでしょうか?
(例えば、書き込むデータが "abc\n" で、読み込まれる際も "abc\n" として読み込まないと条件を満たさない?)

3:バイナリストリームは、テキストストリームと違い文字の変換などは行わないですよね?
(改行文字の変換は行われないなど?)

見当違いな解釈をしている気がしてなりません…(間違えていると思います)
大変初歩的な質問で本当に申し訳ないのですが、上記の定義の正しい解釈についてご教授して下さると幸いです。
どうか宜しくお願いします。

調べてみたのですが…

マイクロソフトや IBM のサイトに記載されているものを拝見させていただいたのですが、同じような記述で私には良く分かりませんでした…

参考にしたテキスト

定義については、新明解シリーズのC言語に記載してあったものを引用させていただきました。

fa11enprince, m.ts10806, yohhoy, atata0319👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

こんにちは。

標準C言語のストリームの定義の解釈の仕方が分からない…

そもそもC言語にストリームの概念はないですよ。
テキスト・ファイルとバイナリ・ファイルの差はありますが、これはWindowsがこの2つを(悲しいかな)厳密に区別するから、それに引きずられているだけかも知れません。


【09/04追記】
規格書(の無料で見れるドラフト)をみてみました。
316ページ「7.21.2 Streams」に記載されています。
規格書にもテキスト・ストリーム、バイナリ・ストリームは定義されていました。位置づけとしてはこれらの条件に該当するものはテキスト・ストリーム、バイナリ・ストリームとしてサポートするというものでしたので、これら以外を許さないという書き方ではなかったです。(質問文にも特にそのような記述があるわけではないので、ここは私の解釈ミスですね。ごめんなさい。)

  1. ターミナル、テープ・ドライブ、構造を持つ(フォルダのあるという意味でしょう)ストレージ・デバイスについて、テキスト・ストリームとバイナリ・ストリームをサポートするそうです。

他の形式を使ってはいけないという記述ではないです。またメモリ・ストリームは含まないようです。
2. テキスト・ストリームは要するに、入出力時に改行文字コードを追加/削除するので書いたものと書かれたもの(読み出されたものではないです)が1対1対応するとは限らないそうです。そして、書いたものと読み出されたものが一致する条件が3つ書かれてます(質問文の3つと同じ)。
「改行文字の直前に空白文字がない。」の記載もありました。行の終わりにスペースを書くこともありますから、一般的なテキスト・エディタで書かれたテキスト・ファイルはこの条件から外れそうです。BOM付きファイルも全部外れますね。
3. バイナリ・ストリームは書いたものと読んだものが一致する、ただし、null文字をストリームの最後に付け加えても良いそうです。
書いた時にはなかったnull文字が最後に追加されていることがあるという意味ですね。HDDなどのセクタ・サイズに合わせるパディングを意識したものと思われますが、バイナリ・ファイルは書いたときと同じサイズで読み出せることを当てにすることが多いので新鮮な驚きです。

更に記述は続いてますが、議題からは外れると思いますので割愛します。


以上を踏まえて改めて回答します。

1:fputc() や fgetc() のように、1つの文字をテキストストリームに読み書させる際は(以下略)

処理系が最終行の終わりに改行文字を要求する場合は、最後に1つの改行文字を出力しておけば定義①内です。
処理系がそれを要求しないなら、何をしようと定義①内と思います。

2:➁の定義における3つの規則は(以下略)

これは「③の定義」の間違いでしょうか?
書いて読んだ時に同じ値が読み出せると条件を満たすことになります。実際にメディアに書かれる内容がそれと一致する必要はありません。

3:バイナリストリームは、テキストストリームと違い文字の変換などは行わないですよね?

(改行文字の変換は行われないなど?)

その通りですね。
書いて読んで一致ですから、通信デバイスはバイナリ・ストリームの条件を満たさないと思います。

ただ、私が間違っている可能性があります。もしかすると相手が書いて自分が読んで一致する場合に条件を満たすかもしれません。(通信相手が同じ処理系であることが条件にありますので、該当しない場面がかなり多いとは思いますが。)

投稿2018/09/03 13:25

編集2018/09/04 03:11
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2018/09/03 14:20 編集

質問中の文章は、CのJIS規格の引用です。
cadet_study

2018/09/03 14:24

Chironian さんお久しぶりです。回答して下さりありがとうございます。 そうなのですか… ならテキストに記載されていた定義は何だったのでしょうかね…
yumetodo

2018/09/03 14:36

いや、ストリームそのものは定義されているでしょう・・・。じゃないとどうやって標準入出力とかファイルIOを定義するつもりで・・・
cadet_study

2018/09/03 15:19

ストリームの定義はあるが、それはテキスト・バイナリに分けて定義されるものではない,ということですか?
Chironian

2018/09/03 15:29 編集

otnさん おおっ、そうなのですか!! しかし、意味不明です。外部I/Oに対して、書いて読んで元の値が読み出せることを言語側で保証できる筈ないですし。 cadet_studyさん お久です。 「ストリーム」自体はyumetodoさんの言う通り、「ある」といって良いですね。 しかし、その定義は「謎」です。書いて読んで一致するかどうかを保証するのはデバイス側の責任です。C言語側がそれを保証することはありえません。 次に、ファイル・ストリームはあると言えます。そして、ファイル・ストリーム限定ならば、テキストとバイナリの別はあります。 また、C++やJava、C#にはストリームの概念がありますが、これらとは全く異なる定義ですし、たぶんあまり真面目に覚えない方が将来の混乱を回避できるだろうと思いますよ。 yumetodoさん なるほど、ファイルとのやり取りを「ストリーム」と読んでいるのですね。 ストリームといえば、ファイル・ストリームやメモリ・ストリームのようにファイル限定でない少し抽象化された概念と捉えていました。でも、ファイル・ストリームだけをストリームと呼ぶのも確かにありですね。迂闊でした。
otn

2018/09/03 15:39

バイナリストリームに関しては、書いた物と読んだ物が一致することを、規格書が処理系に求めています。(例外記述は有り)
cadet_study

2018/09/03 16:13

Zuishin さん,回答して下さりありがとうございます。お世話になっております。 私の持っているテキストにも stdin stdout の説明で同じようなイラストを見かけました。
cadet_study

2018/09/03 16:19

Chironian さん,お返事ありがとうございます。 C++ではストリームの概念がしっかりあるのですね。C言語の勉強がある程度定着したらC++を勉強したいと思っていましたので、そのような認識でこの質問について考えることにします。正直難しいですね…
cadet_study

2018/09/03 16:43

ということは、これはテキスト(ファイル)ストリーム・バイナリ(ファイル)ストリームにおける定義?ということですかね… (プラス標準ではなくJIS規格のもの) ややこしいです…
Chironian

2018/09/03 17:33

otnさん そうなのですか。やっぱりびっくりです。Zuishinさんが書かれているようにファイル・ストリームはストレージだけではないので、書いたものが読めることを保証することは一般にできません。(stdin, stdout等もFILE*型ですので、これらも「ファイル・ストリーム」として理解しています。linuxのデバイス・ファイル的な概念です。) 恐らく、その規格書の記述はストレージに限定されているのではないでしょうか? cadet_studyさん 更に、ストレージ限定と思います。stdin, stdout, stderrは、片方向なので書いて読むことはできません。まして書いたものが読めることを保証するのはありえないですね。 また、双方向の通信デバイスが接続されたファイル・ストリームも考えられるでしょう。通信デバイスの場合、書いたものが読めることを保証するのはナンセンスです。
otn

2018/09/04 01:50

何故「言語側で保証できない」とおっしゃっているのか理解できなかったのですが、ようやく理解できました。 求められている事を勘違いしていませんか?書いた物が読める事は誰も求めていません。 読んだ物が書いた物と一致する事を求めています。 読めないならこの記述とは無関係です。
Chironian

2018/09/04 03:14

otnさん おっしゃる通りかもです。この条件を満たさないものは単にテキスト・ストリームでもバイナリ・ストリームでもないだけでC言語として取り扱えないというものではないですね。ちょっと勘違いしてました。
otn

2018/09/04 04:13

> ただし、null文字をストリームの最後に付け加えても良いそうです。 これは、ファイルサイズが任意のバイトサイズを取れない、つまりファイルサイズをバイト単位で記録していないファイルシステムを考慮しての事です。固定長レコードからなるファイルで、レコード数のみを記録しているケース。 ファイルサイズがバイト単位で記録されるファイルシステムであれば、こういうことは起こらない。
otn

2018/09/04 04:15

一度書いたテキストストリーム、バイナリストリームを必ず読み直す事が出来なければならないとはどこにも書いてないので、端末などがその他と言う事はないと思います。テキストストリームでしょう。
cadet_study

2018/09/04 07:51

Chironian さん、詳しい規格の説明をして下さりありがとうございます。 ということは、ファイルなどのストレージに結び付くストリームの定義の説明で、ファイルに書いたデータを再びプログラム上に読み込む際に、書き込んだデータと一致するのを保証するのが➂の条件で、書き込むデータと、ストリームで書かれるデータは一致するとは限らない,ということですか?
cadet_study

2018/09/04 07:56

ファイル ← ストリーム(変換する可能性あり)  ← 書き込むデータ…A ファイル → ストリーム(変換の可能性あり) → 読み込んだデータ…B → A と B でデータの状態が一致するには、3つの規則を守る必要がある?
Chironian

2018/09/04 10:33

> A と B でデータの状態が一致するには、3つの規則を守る必要がある? この部分は標準規格に準拠していない処理系はあまりないと思いますので、その通りです。 この3つの規則を一部守って無くても(改行前のスペースやBOMコードなどが有っても)AとBでデータの状態が一致する処理系も少なくないと思います。
cadet_study

2018/09/04 10:54

Chironianさん,ありがとうございます。 otn さんにもご教授いたただいたのですが、最後の条件である「最後が改行文字である」が、なぜその必要があるのかいまいち分からないので、よろしければ何か例を用いてご説明いただけないでしょうか?
Chironian

2018/09/04 12:17

昔は色々なCコンパイラが乱立していたので、改行で終端していないファイルの最後に改行を付け加える処理系が有ったのかも知れません。記憶は定かではありませんが有ったような気もします。昔はこの辺かなり混乱していましたから。 そして、そのような処理系(コンパイラ)でも標準規格準拠を唄えるようにするために必要な条件に当たりそうです。つまり、そのようなコンパイラも救いたかったのかも知れません。 標準規格と言っても強制力はありませんので準拠するコンパイラが少なければ単なる絵に書いた餅ですから。
cadet_study

2018/09/04 13:42

なるほど… 標準規格に100%準拠する必要はないのですか… 確かに visual studio では構造体の可変長配列は最後のメンバである必要はないなど、色々変えてしまっていますのでややこしいです…
cadet_study

2018/09/05 03:07

Chironian さん、最後にこのことについて質問させてください… 条件の「データが表示文字と水平タブ,改行文字のみで構成される」のうち、なぜ制御文字が「改行文字・水平タブ "のみ" 」に限定される必要があるのか分かりませんでした。 何故そのように限定される必要があるのか,ご教授願いたいです。宜しくお願いします。
Chironian

2018/09/05 03:17

恐らく、その定義を決めた当時、多くの「普通の」表示用のテキスト・ファイルは表示出来ない文字はHT, VT, 改行だけしか使っていなかったのではないかと思います。 現代では状況は変わっています。今はVTを使うケースは見たことないですが、昔はラインプリンタやテレタイプへ出力する際に有用だったのかも知れません。
cadet_study

2018/09/05 04:32

なるほど… >現代では状況は変わっています。 現在の状況が変わっているが、その定義自体が古いままになっている、ということですか? 改行文字と水平タブ以外の制御文字をもし書き込み(垂直タブ文字や警告文字など?)、読み込もうとした際は一致しない可能性があることになってしまうのでしょうか?
cadet_study

2018/09/05 04:37

otn さんに「1つ目の条件は、文字集合を限定しないためでは無いかと思います。ASCII上位互換でない文字集合もありますので。」とご説明していただいたので、その文字エンコード関係のことを定義で言っているのかと思っていたのですが、その解釈の仕方がいまいち自分の中でできないんです…
Chironian

2018/09/05 07:57

> 現在の状況が変わっているが、その定義自体が古いままになっている、ということですか? ですね。未だに改行前のスペース削除を許容し、VTは有っても化けることを許さないけどBOMがあると化けることを許容するとか、あまりに現代の必要からかけ離れていると感じます。 メンテナンスされている定義とは思えません。 > 改行文字と水平タブ以外の制御文字をもし書き込み(垂直タブ文字や警告文字など?)、 VT(垂直タブ)は有っても良い文字の1つと書かれてますよ。 > 読み込もうとした際は一致しない可能性があることになってしまうのでしょうか? 理論上、標準規格に準拠した処理系でもその可能性があるということです。 実際には現代の処理系にそのような時代遅れなものはないだろうと思いますが。 > その解釈の仕方がいまいち自分の中でできないんです… ごめんなさい。長いので他のコメント・リストまでは目を通していないです。 ちょろっと見てみましたが、なかなか難解な議論が続いているようで把握するのは厳しいです。
cadet_study

2018/09/05 08:04

Chironianさん、ありがとうございます。otn さんの説明を伺いつつ、この解釈の仕方については判断してみることにしてみます。
cadet_study

2018/09/05 11:02

Chironianさん、 > VT(垂直タブ)は有っても良い文字の1つと書かれてますよ。 ということは、1つ目の条件の解釈の仕方としては、「表示文字と空白類関係の制御文字に限定される」ということになるのでしょうか?(書式送りの文字も有っても問題ないのでしょうかね)
cadet_study

2018/09/05 12:37

それが可能なら、ソース基本文字集合(ソースファイル・テキスファイルで使用可能な文字集合)が原因で、その条件が必要になると思います。
Chironian

2018/09/05 19:16

> 1つ目の条件の解釈の仕方としては、「表示文字と空白類関係の制御文字に限定される」ということになるのでしょうか? 字面通り、VT, HT, 改行文字の3つと思いますよ。拡大解釈はしない方がよいと思います。 > (書式送りの文字も有っても問題ないのでしょうかね) 「書式送りの文字」がVTでも HTでもないという意味でしたら、その場合に文字化けしてもその処理系は標準規格内ということになります。 「書式送りの文字」がVTか HTという意味でしたら、その場合に文字化けするとその処理系は標準規格違反ということになります。 標準規格を守るコンパイラは多いので、テキスト・ファイルにはVT, HT, 改行以外の非表示文字は使わないほうがマルチプラットフォーム対応しやすいです。 > それが可能なら、ソース基本文字集合(ソースファイル・テキスファイルで使用可能な文字集合)が原因で、その条件が必要になると思います。 仰る意味がよく分からないですが、VT, HT, 改行以外の非表示文字があるテキスト・ファイルを処理させた時の動作はその処理系の仕様によります。C言語標準規格は仕様を定めず、処理系に任せているというだけです。 標準規格で定められていない部分は当然コンパイラ開発者が仕様を決定しますし、標準規格で定めらている部分もコンパイラ開発者が自身で開発するコンパイラの仕様を決定します。当たり前ですね。 標準規格はその際のリファレンスに過ぎません。かなり強力なリファレンスとは言えますが、罰則があるわけではないので、その内容が完全に守られていると信じ込むと痛い目にあいますよ。
cadet_study

2018/09/05 19:39

すみません、その解釈は間違えてました。わざわざありがとうございます。
cadet_study

2018/09/05 19:41

最後に、 バイナリストリーム(モード) → 任意の文字の並びや任意のデータ型を扱うことができる(null文字の付加を除き変換などなし,そのまま扱う) テキストストリーム(モード) → 条件つきで(変換・一致するためのルールなどを伴い)文字の並びを扱うことができる(文字によっては規約に合わせるために変換する場合あり、データを文字として認識し、対処する) のイメージでよろしいでしょうか?
Chironian

2018/09/05 19:46

その通りと思います。
cadet_study

2018/09/05 21:09

長いコメントにもお付き合いいただき本当にありがたいです。 本当に助かってます。 "標準規格は強力なリファレンスだが、鵜呑みににはしない"を忘れないようにします。 今回も手助けいただき本当にありがとうございました。
cadet_study

2018/09/05 23:00

何度も確認してすみません。 3の"読み込み〜"の文のことなんですけど、書き込みデータ = 読み込みデータになるための条件が3つ必要なだけで、テキストファイル(ソースファイルではない)に条件外の制御文字を書き込む分には問題ないですよね?
Chironian

2018/09/06 03:37

「問題ない」の意味によります。 標準規格で定義されていないのでその時の振る舞いは実装依存となります。実装依存で問題ないなら問題ありません。実装依存で問題あるなら問題あります。 後者はマルチプラットフォーム対応する時に問題になる場合があります。マルチプラットフォーム対応をガン無視できる開発(例えば、Windows APIに強く依存したプロジェクトなど)なら問題にはならない筈です。
cadet_study

2018/09/06 06:37

> 標準規格で定義されていないのでその時の振る舞いは実装依存となります。 そうなのですね… ソースファイルの説明は規格にあったので、テキストファイルの方はどうなのか気になり質問しました。
cadet_study

2018/09/06 06:43

改行・タブ以外の制御文字をテキストファイルで扱えるかは実装依存(処理系定義)なのですね。 ありがとうございます。
cadet_study

2018/09/06 16:25

そのような解釈で大丈夫でしょうか…
Chironian

2018/09/06 18:50

> 改行・タブ以外の制御文字をテキストファイルで扱えるかは実装依存(処理系定義)なのですね。 > そのような解釈で大丈夫でしょうか… 大丈夫か?と聞かれるとなんともですが、大雑把な理解としてはそれで良いと思いますよ。
cadet_study

2018/09/07 01:04 編集

ごめんなさい!大分雑に書いてしまっていました… しっかり書くと、 テキストストリームにおいて、一致条件外の制御文字の書き込みは規定されていないプラス、テキストファイルで扱えるかも未規定のため、その動作は実装依存(処理系定義) になる、という解釈で…
cadet_study

2018/09/07 01:07 編集

つまり実装依存で、ストリームが条件外の制御文字に対応可能なら、結果としてテキストファイルに書き込み可能(書き込んだときにファイルが扱えるかが問題になるが), という意味で捉えているのですが… (読み込みで一致する保証はないですけど…)
Chironian

2018/09/07 01:17

> テキストストリームにおいて、一致条件外の制御文字の書き込みは規定されていない よく読みましょう。テキストストリームの条件に「書いて良い文字/いけない文字」は書かれていません。 それは、テキストストリームへ書いて読んで一致する条件に有るだけです。 FILE* 経由で書ける文字について定義があるかも知れません。 ないかも知れないですが、その解釈は関係者一同で概ね一致しているだろうと予想します。コンピュータの一般的な仕組みでファイルI/Oで書けるものは全部書けるという理解が一般的と思います。 そして、もし、それに反するテキストストリームを許容するのであれば、その旨がここに明記されていても良さそうな気がします。
cadet_study

2018/09/07 09:25 編集

そうですね… FILE *経由で書ける文字について制限があるか調べてみましたが、規格での説明にはなかったので制限はないと分かりました。 何から何までありがとうございました。
guest

0

ベストアンサー

まず、これは、ファイルがバイトの並びでないようなOS(メインフレームとか)も考慮した記述であり、Unix系OSもWindowsもファイルはバイトの並びなので、テキストストリームもバイナリストリームも大きな違いは無いです。Windows以外に於いてはどちらも無変換で読み書きされますし。

(追記)質問中の文章は、JIS規格書の引用のようですが、規格書はいろいろな環境やコンパイラを許容するために、ややわかりにくい記述になっています。どんな環境を許容するためにこういう記述になっているのかとかは、規格中に書いてないんですよね。

1:fputc() や fgetc() のように、

定義に外れません。
(追記)1行を一度に出力する必要はありません。改行文字が出力された時点で、そこまでが1行になります。

2:➁の定義における3つの規則

とは何のことでしょうか?

3:バイナリストリームは、テキストストリームと違い文字の変換などは行わないですよね?

一般的にはそうです。変換しません。
この記述だけ満たせば良いなら、書くときに可逆変換して、読むときに逆変換して、書いたデータと読んだデータが常に一致すれば良いことになりますが。

##追記
「ファイルがバイトの並びでないような」というのは、「ファイルがレコードの並び」であるケースです。
この場合、テキストストリームだと、プログラム上の行がファイルのレコードにマッピングされます。
プログラムから改行文字を出力すると、今書いているレコードに書くのをやめて、次からは次のレコードに書くことにします。改行文字自体はファイル中に保持されません。
レコードが固定長の場合、行末の空白の有無を判断できないので、③のような記述になります。例えば、空白でパディングするレコード長10のファイルの場合、"ABC"と書いたのか、"ABC "と書いたのか、ファイルを見ても判断できません。

投稿2018/09/03 13:20

編集2018/09/03 15:26
otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cadet_study

2018/09/03 14:28

すみません,書き間違えました。➂で列挙した3つの・に続く文章です。
cadet_study

2018/09/03 14:30

otn さん,回答して下さりありがとうございます。 よろしければ1の定義に外れない理由についてご教授していただきたいです。
otn

2018/09/03 14:48

1については追記しました。 ③については、ファイルがレコード形式の場合について追記しています。これが③の2つめ3つめの条件がある理由です。1つ目の条件は、文字集合を限定しないためでは無いかと思います。ASCII上位互換でない文字集合もありますので。例えば https://ja.wikipedia.org/wiki/EBCDIC
otn

2018/09/03 15:32

アドバイスとしては、Unix/Linux/Windowsを使っている限りに於いて、C言語規格のこのあたりは忘れて良いと思います。Unix/Linuxだと、テキストストリームもバイナリストリームも違いは無いし、Windowsでもテキストストリームは改行文字の変換があるだけです。
cadet_study

2018/09/03 15:55

なるほど…  改行が入力された時点でデータを1行と定義するため問題ないのですね。 ➂の、レコード形式で固定長の場合は空白でパディングされたら見分けがつかないから,ということには納得しました。
cadet_study

2018/09/03 15:59

URLを拝見させていただきました。知識不足ながら、ASCII と EBCDIC の制御コードが異なるものがあることを知りました。このような差異があるため、➂の条件1があるのですね。納得しました。
cadet_study

2018/09/03 16:08

➂の最後の条件の,「最後の文字が改行文字である」が何故その必要があるのかを考えたのですが、思いつきませんでした。 お手数をおかけし申し訳ないのですが、何か例を用いてご説明していただけませんか?
asm

2018/09/03 17:48

最終行が改行文字以外で終わっている時に改行文字をくっつけた文字列を読み取っても テキストストリームとしては合法です。
otn

2018/09/04 01:43

> ➂の最後の条件の,「最後の文字が改行文字である」が何故その必要があるのかを考えたのですが、 レコード形式の場合、末尾に改行があるのか無いのか判断できなくなってしまうので、改行有りに決めうちするのでしょう。
cadet_study

2018/09/04 07:29

ということは、レコード形式の場合は、レコード単位でデータを読み取る場合がある (fscanf 関数や fgetsなどを使った場合?)ので、可搬性を持たせるため(改行がファイルに保持されるかの有無に問わず)に必要,ということですか? (逆に改行を書き込まないと区切りをつけることができず、後方のデータまで読み込んでしまい、書き込んだデータと一致しなくなるため?でもそもそも改行をつけることで1行のデータ単位をテキストストリームで定義しているわけですから、当たり前なことを言ってる気がします…)
otn

2018/09/04 07:38

ファイルの1レコードが、プログラムでの1行と対応して、改行をファイル中に保持しない場合、レコードに次のレコードがあれば、そのレコードに対応する行に元は改行があった事が分かるが、最後のレコードについては、元の行に改行が付いていたのかどうかの情報がファイルに残らないです。
cadet_study

2018/09/04 07:38

asm さん,最終行に改行文字が必要かどうかは処理系定義,と書かれていました。もし必要で、かつ改行文字を付加してない場合は、処理系が改行文字を付加したとしても合法、ということでしょうか? また、テキストストリームは最低でも254文字をサポートし、それを超えた文字をサポートできるかは処理系定義,とも書かれていました。 もし254文字までしか処理系がサポートできない場合、254文字を超えてしまったらどうなってしまうのか疑問になりましたので、そのことについてもご教授して下さると幸いです。
otn

2018/09/04 08:05

1つめ。 良いように読めます。 2つめ。 254文字の環境限界というのは、処理系に対する要求ですが、処理系定義のその値を越えた場合は、未定義動作だと思います。規格の専門家ではないので、多分、ですが。 処理系のありそうな対応としては、「エラーを返す」でしょうか。
asm

2018/09/04 09:11

> ホスト環境内でテキストを表現するための規約に適合させるために、入力と出力の際に文字を変更・付加・削除しても良い。 なので、改行文字の末尾への追加は合法でしょう。 254文字以上を許容できない処理系において超えた場合はストリームとしては未定義動作です。 fwriteを用いた場合は、先頭から0~254文字書き込み、後は破棄が起こり得ます。 fputs/fprintfについては、失敗が起こりエラーが返る事があります。その結果ストリームの中身がどうなってるかは未定義のようです。
cadet_study

2018/09/04 09:19

asm さん, > 254文字以上を許容できない処理系において超えた場合はストリームとしては未定義動作です。... 未定義の部類に入ってしまうのですか… fwrite や fprintf で、もし254文字以上が許容されない場合、そのようなことが起こってしまうのですね…
cadet_study

2018/09/04 09:31

otnさん, 先程の「最後が改行文字である」の自分の解釈は問題なさそうでしょうか… (間違えていましたらご指摘お願いします。)
cadet_study

2018/09/04 09:43

やはり「最後が改行文字である」の部分だけいまいち解釈の仕方がわからないです… (テキストストリームが扱う1データは改行文字までなので、そのファイルが改行文字を保持しようが、レコード形式で保持されない場合でも、改行が書き込まれようとしたときにレコードが区切られるので、当たり前なことを言っているように思えてしまいます…)
otn

2018/09/04 11:44

Windowsのメモ帳のような、改行文字やファイル終わりが目に見えないエディタを考えてください。 aaaaaaa bbbbbb cccccc と見えた場合、英字の直後が改行なのか、空白があって改行なのか、カーソルを動かさないことには、見ただけでは分かりませんよね。これが「・改行文字の直前に空白文字がない。」という条件が必要な理由です。また、aaaaaaaやbbbbbbの後に(空白の有無はともかく)改行があることは分かりますが、ccccccの後に改行はあるでしょうか?これは見ただけで分かりませんよね。これが、「・最後の文字が改行文字である。 」という条件が必要な理由です。
cadet_study

2018/09/04 13:36

なるほど… 「最後」というのは、特にファイルの最終行のことを言っていたのですね… 次の行(またはレコード)があれば、改行を保持しなくても改行があったと認識し、1つの行として扱えるが(あってこそ行として区切られる)、 最終行は次に続く行もしくはレコードがないため、1つの行・レコードとして100%認識させるために (最終行に改行が必要ない処理系はなくても問題ないが、必要な処理系だった場合はどこがその行の明確な終わりだか分からないため、場合によっては空白などもついてしまったりするかもしれないから…)必要ということでしょうか?
otn

2018/09/04 13:50

違います。 レコードがあれば行と認識できます。 最終行の読みとりの時に、改行付きでプログラムに返すのか、改行無しでプログラムに返すのか、ファイルにはどちらにするか情報がありません。そこで、最終行は改行有りで返すことに決めます。これが書き込んだデータと一致するためには、書くときもファイル末に改行を書くという条件が必要です。 もちろん、最終行は改行無しで返すことに決めてもかまいませんが、その場合の規格では、読み書きのデータが一致するためには、最終行には改行を付けないという条件に変わります。
cadet_study

2018/09/04 14:39

最終行を改行ありで返すと決めたため、実際に書き込むデータも改行を付加しないと、 付加しなかったデータの場合、付加しなかった文字+改行文字になってしまい、書き込んだデータ(改行なしで書いた)と読み込んだデータ(改行なしで書き込んだデータ+改行文字がつく)が一致しないこととなる,ということでしょうか?(逆のつけないで返すと決めた場合も同じようにして)
otn

2018/09/04 15:20

そうです。
cadet_study

2018/09/04 15:39

なるほど… (一応なのですが、最終行ではない普通の行も、改行文字が保持されるかの有無に関わらず改行つきで返りますよね) 最後に➂の「データが表示文字と水平タブ,改行文字のみで構成される。」の理由として、 「文字集合を限定しないため」と説明していただき、しばらく考えてみたのですが、正直良い解釈が自分の中でできませんでした。先程のような解釈のご説明をしていただけないでしょうか? (具体的に疑問を持った点は、「文字集合を限定しないため」と、なぜ改行文字と水平タブに制御文字が限定されるか,の2つです。) (otn さんにはとても詳くて分かりやすい説明を最初にして下さり、非常に助かりましたのでベストアンサーにさせていただこうと思っています。最後までお付き合いしていただけると幸いです。)
otn

2018/09/05 08:51

テキストストリームは改行で区切られているので、改行が扱えることは必須です。 水平タブは分かりません。挙げなくて良かったのにと思います。規格の別の部分で、水平タブが役割を持って書いてあるのかも。 JIS規格書が http://www.jisc.go.jp/app/jis/general/GnrJISSearch.html で読めるので、読んでみてください。検索で、JIS X3 を検索します。
cadet_study

2018/09/05 11:04

ありがとうございます。もしかしたら、(ソース)基本文字集合と関係があるかもしれないと思っています。
cadet_study

2018/09/05 12:54

規格や他サイトで調べてみたところ、 実行基本文字集合(実行時に使用できる文字集合)には、警告・後退・復帰文字が含まれている必要があると記載されていたのですが、ソース基本文字集合(ソース・テキストに使用できる文字集合)には、書式送り・水平タブ・垂直タブのみしか含まれることを要求していませんでした。
cadet_study

2018/09/05 12:56

もしかしたら、書式送り・水平タブ・垂直タブ以外の制御文字が、ソース拡張文字集合に含まれないことがある場合を考慮するために、このようなルールにしたのでは、と思いました。
cadet_study

2018/09/05 13:01

文字エンコードの関係かなと一度思ったのですが、 表示文字・制御文字の定義がいずれも「文化圏固有の文字集合の要素(その地域で対応する文字コード内のもの)」だったので、これはこの条件の理由の要素ではないと思いました。
otn

2018/09/05 13:16

テキストストリームは、実行時のデータの話なので、ソース文字集合とは無関係ですよ。
cadet_study

2018/09/05 13:50

うーん、正直もう理由がわからないですね…
cadet_study

2018/09/05 13:55

>テキストストリームは、実行時のデータの話なので, とりあえず、テキストストリームは、読み書き時のデータを一致させたい際に、表示文字と、制御文字の改行と水平タブの組み合わせなら、ストリームの機能として一致することを保障させる、ということを覚えておくことにします。
otn

2018/09/05 14:41

前にも書きましたが、Unix/Linux/Windows環境であれば、テキストストリームもバイナリストリームもほぼ同じで、読んだものと書いた物は一致します(Windowsのテキストストリームは\rを書いた場合、処理系によっては一致しない)ので、メインフレーム独自OS上のCを使うことにでもならない限り、あまり気にする必要は無いです。
cadet_study

2018/09/05 16:02

ありがとうございます。 最後に確認したいのですが、仮に規格のように、2つのストリームを厳密に分類したい場合は、 バイナリストリーム → 任意の文字の並びや任意のデータ型を扱うことができる(null文字の付加を除き変換などなし,そのまま扱う) テキストストリーム → 条件つきで(変換・一致するためのルールなどを伴い)文字の並びを扱うことができる(文字によっては規約に合わせるために変換する場合あり、データを文字として認識し、対処する) という捉え方で正しいでしょうか?
cadet_study

2018/09/05 21:11

長いコメントにもお付き合いいただき本当にありがたいです。 理解力がなく本当に申し訳ないです。 最後までお付き合いいただき本当にありがとうございます。
cadet_study

2018/09/05 23:01

何度も確認してすみません。 3の"読み込み〜"の文のことなんですけど、書き込みデータ = 読み込みデータになるための条件が3つ必要なだけで、テキストファイル(ソースファイルではない)に条件外の制御文字を書き込む分には問題ないですよね?
otn

2018/09/06 01:03

> 最後に確認したいのですが、 ちょっとニュアンスが分からない部分がありますが、概ね正しいと思います。 > 条件外の制御文字を書き込む分には問題ないですよね? そうですね。3つの条件は一致するための条件です。 ただし、処理系が条件以外の制御文字を削除してしまっていてもその処理系は規格適合だと思います。
cadet_study

2018/09/06 06:33

なるほど… テキストファイルについての明確な定義がなかったので質問させていただきました。(ソースファイルについての説明はあったので気になりました。)
cadet_study

2018/09/06 06:34

実装依存になるのですね… 最後までありがとうございました。
cadet_study

2018/09/06 06:46

改行・タブ以外の制御文字をテキストファイルで扱えるかは処理系定義なのですね… ありがとうございます。
cadet_study

2018/09/06 16:25

そのような解釈で大丈夫でしょうか…
cadet_study

2018/09/06 23:37

すみません!大分雑に書いてしまっていました… しっかり書くと、 テキストストリームにおいて、一致条件外の制御文字の書き込みは規定されていないため、その動作は実装依存(処理系定義)になる、 という解釈になるのでしょうか?
cadet_study

2018/09/07 01:12 編集

つまり実装依存で、ストリームが条件外の制御文字に対応可能なら、結果としてテキストファイルに書き込み可能(書き込んだ制御文字がテキストファイルで扱えるかが未規定ですが),という意味で捉えているのですが… (読み込みで一致する保証はないですけど…)
otn

2018/09/07 04:58

> 改行・タブ以外の制御文字をテキストファイルで扱えるかは処理系定義なのですね… 違います。それはあくまで、書いた物と同じ物が読める条件です。 実行基本文字集合はどの処理系でも扱える必要があります。制御文字だと、水平タブ、垂直タブ、書式送り、警報、後退、復帰、改行。 > テキストストリームにおいて、一致条件外の制御文字の書き込みは規定されていないため、その動作は実装依存(処理系定義)になる、 違います。動作が実装依存じゃなくて、読み書きが一致するかどうかが実装依存です。 > つまり実装依存で、ストリームが条件外の制御文字に対応可能なら、結果としてテキストファイルに書き込み可能(書き込んだ制御文字がテキストファイルで扱えるかが未規定ですが),という意味で捉えているのですが… は、括弧内を除いて正しい。括弧内は意味が分かりません。
cadet_study

2018/09/07 11:10 編集

>括弧内は意味が分かりません。 すみません,テキストファイルに保持できる文字は全部の文字とは限らないと勝手に思いこんでいまして… やはり違いましたか…規格でそんな説明はどこにもなかったので間違いだと思って質問しました。
cadet_study

2018/09/07 11:41

→ 任意の実行基本・拡張文字集合の文字を、テキストストリームを介して、(テキスト・バイナリ)ファイルに書き込み、データとして保存することは勿論できる… しかし、そのファイルに保存された文字が、一致条件外の文字だった場合は、その条件外の文字は、読み取りの際に読み込まれず、プログラム上では条件外の文字を除いた文字並びになってしまうかもしれない… ということ感じでしょうか…
pepperleaf

2018/09/07 12:02

なんか、現実とは外れた架空の話になりつつあるように感じますが、どうなのでしょう。Unixを開発する過程で生まれたC言語ではファイルはただのバイトストリーム。その後、事務系とか、汎用機との整合性など計られたとは思うのです。ここで、テキストストリームを議論するのは意味あるのでしょうか? また、最近の Unicode、特にUTF-16 とかだと、16bitのほぼ全域を使用します。この場合、ここで言う、テキストストリームとなんでしょう?
otn

2018/09/07 12:33

> すみません,テキストファイルに保持できる文字は全部の文字とは限らないと勝手に思いこんでいまして… > やはり違いましたか…規格でそんな説明はどこにもなかったので間違いだと思って質問しました。 そんなことは規格にはありません。 > しかし、そのファイルに保存された文字が、一致条件外の文字だった場合は、その条件外の文字は、読み取りの際に読み込まれず、 そんな具体的なことは規格は何も言っていません。一致しないかも知れないと言うだけです。 規格の裏の意図をくみ取るには知識・経験が足りていないと思いますので、今のところは規格を文字通り読んでください。
cadet_study

2018/09/07 12:34

すみません、ただの自分の興味本位で質問しているだけなので…
cadet_study

2018/09/07 12:36

分かりました。 何から何までありがとうございました。
otn

2018/09/07 12:40

もう一度書きますが、Unix/Linux/Windows環境であれば、テキストストリームもバイナリストリームもほぼ同じで、読んだものと書いた物は一致します(Windowsのテキストストリームは\rを書いた場合、処理系によっては一致しない)。 それ以外のOSや、ファイルがバイトストリームで無いファイルシステム、ASCII互換で無い文字コードセットなどの知識があまりない状態で、想像を膨らませてもあまり意味が無いです。
cadet_study

2018/09/07 12:46

そうですね、知識がまだまだなレベルなのは皆さんのコメントをいただき痛感しています。 知識力を上げていき頑張ります。ありがとうございます。
guest

0

1:fputc() や fgetc() のように、1つの文字をテキストストリームに読み書させる際は、ストリームの➀の定義に外れることになるのでしょうか?(外れるとしたらどうなるのですか…)

いいえ、外れません

2:➁の定義における3つの規則は、読み込まれるとき・書き込まれるときのテキストストリーム上のデータの状態を指し、読み込み・書き込みの際の両方でストリームのデータがその条件を満たしていなければならない,ということなのでしょうか?

(例えば、書き込むデータが "abc\n" で、読み込まれる際も "abc\n" として読み込まないと条件を満たさない?)

②とは③の間違いでしょうか? ③と解釈して答えます。
違います。テキストストリームでは、読み込むときと書き込むときとでは内容が異なる場合があるということです。

3:バイナリストリームは、テキストストリームと違い文字の変換などは行わないですよね?

(改行文字の変換は行われないなど?)

はい、行いません

細かいことに囚われ過ぎだと思います。重要なことは、バイナリストリームは入力と出力が一致するが、テキストストリームは一致しないことがある、ということだけです。

投稿2018/09/03 13:18

yuki23

総合スコア1448

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cadet_study

2018/09/03 14:53

回答して下さりありがとうございます。 そうですよね… こだわりすぎている気が自分でもします…
guest

0

前に書いた
拡張子とファイルのフォーマット - yumetodoの旅とプログラミングとかの記録
が近いと思うのでどうぞ。

~~Cにはテキストストリームやらバイナリストリームという概念はありません。~~と思ったらそうでもなかったのか・・・

投稿2018/09/03 14:10

編集2018/09/04 04:18
yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cadet_study

2018/09/03 14:32

yumetodo さん,お久しぶりです。回答して下さりありがとうございます。 ありがとうございます。拝見させていただきます。
cadet_study

2018/09/03 14:47

テキストファイルの説明の部分があまり分かりませんでしたので、教えて下さるとありがたいです。
yumetodo

2018/09/03 14:50

どのへんでしょう?
yumetodo

2018/09/03 14:51

ある一つの文字コードによってエンコードされたbyte列のみで構成させるファイルのことをテキストファイルと呼ぶわけですが
cadet_study

2018/09/03 14:58

byte 列を文字コードに沿った文字に変換して表示している形式がテキストファイル,という意味で合っていますでしょうか?
yumetodo

2018/09/03 21:14

違いますね・・・ まず文字コードという概念があってそれに基づいて文字列をエンコードしてbyte列としてコンピュータ上では扱っています。 ある(広義の)binaryファイルがあったとき、すべてのbyteにおいてある一つの文字コードでエンコードされたbyte列であるならば、テキストファイルと呼べます。
cadet_study

2018/09/04 07:02

難しいです… エンコードについて私が知識不足であると思ったため、調べさせていただきました。 https://wa3.i-3-i.info/word1894.html そのファイルに書き込まれた全てのバイト並びが、文字列をエンコード(文字エンコードを利用して対応するビット並びに変換)したものであれば、そのファイルはテキストファイルと呼ぶ,ということですか? (たとえその表示形式がビット並びであろうとも)
yumetodo

2018/09/04 07:45

表示形式・・・?
cadet_study

2018/09/04 08:02

テキスト形式(abcde) バイナリ形式 (00121...これは適当)で表示されているってことです。 それがどちらも文字列をエンコードしたバイトならびなら、どちらもテキストファイルと呼べるという意味だとおもったのですが。
yumetodo

2018/09/04 08:07 編集

それはbyte列をどう表示するかというテキストビュワーなりバイナリエディタなりの実装上の問題で無関係です。
cadet_study

2018/09/04 08:13

エディター関係の実装上の問題なのですか… てっきりその表示形式によってファイルの分類を分けていると思っていました。 教科書に書いてあったテキストファイルの説明・バイナリファイルの説明がそのようなもので、まるで違って目から鱗の状態です。
cadet_study

2018/09/04 08:15

すみません,では最後の (たとえその表示形式がビット並びであろうとも) は関係ないということで、先程私がした解釈で問題ないでしょうか?
yumetodo

2018/09/04 08:16

それは解説に使ったソフトウェアではそうだと言うことでしょう。 そもそもファイルにしろなんにしろ人間の目には見えんので(磁界やら電子やらが見えるわけがない)、ソフトウェアで見えるように表示してあげることで観測しているわけです。
yumetodo

2018/09/04 08:17

>すみません,では最後の (たとえその表示形式がビット並びであろうとも) は関係ないということで、先程私がした解釈で問題ないでしょうか? 99%正しいと思いますが、一点。 Cで文字列といえば、null文字で終端した文字の列を指すのですが、テキストファイルにはそのような要件はありません。
cadet_study

2018/09/04 09:07

そうでしたね… ファイル出力の関数(fputsなど)の処理にnull文字は書き込まない、と書いてありました。 正確には「文字列」→「文字の並び(表現が似ていますが)」と、先程の解釈で変更する必要があると思いました。
cadet_study

2018/09/05 21:04

理解力がなく何回も質問してしまい申し訳ないです。 本当に助かってます。長いコメントにもお付き合いいただき本当にありがとうございました。
yumetodo

2018/09/07 07:20

この質問もだいぶ長引くなぁ、ぜひQiitaかどこかに、この質問を通じてわかったことを自分なりにまとめて記事にしていただきたいもの。
cadet_study

2018/09/07 08:18

>この質問もだいぶ長引くなぁ 本当に申し訳ないです… 周りに質問できる人が誰もいないのでどうしても…
yumetodo

2018/09/07 08:58

長引くこと自体は悪くないですが、単にoutputし直したほうがいいんじゃないかな?という意味合いでした
cadet_study

2018/09/07 11:43

そうですよね、整理しながらまとめようと思います。
guest

0

テキストストリームについては、
printfで書き込んでコンソール出力をコピペするとどうなるか
を考えるとわかりやすい気がします。

最終行に\nがくっつくかもしれませんし、くっつかないかもしれません。
末尾の空白は消えているかもしれません。
印字不可能文字が?等で置換されているかもしれません。


使う側としては
テキストモードでファイルを開くとwindowsで"\r\n"←→"\n"の変換が行われてたまにめんどくさい
って事を覚えとくだけでいいと思います。

投稿2018/09/03 16:31

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cadet_study

2018/09/03 16:45

asm さん,回答して下さりありがとうございます。 そうですよね… それを踏まえておけば問題ないと思うのですが、どうも気になってしまい質問させていただきました。
cadet_study

2018/09/03 16:51

レコード形式のファイルには改行文字は保持されないと教えていただいたのですが、その他の形式では改行文字が保持されることもあるのですか?
asm

2018/09/03 22:54

読み取り方が多彩にできる質問で困っています… Windows以外の多くのPC(Linux,Unix)ではファイルはバイト列を保持するストレージで 改行文字の変換などを行わずにストレージ内に保持しています。 メインフレームは詳しくありませんが、レコード形式であろうとも改行文字をストレージ内に保管(or保持)する事は実装者次第ではありそうな気もします。
cadet_study

2018/09/04 05:25

質問が抽象的でした,すみません。 なるほど… ありがとうございます。
pepperleaf

2018/09/04 11:39

今回の話題からは、ちょっとずれますが、 メインフレーム、、、Fortran, COBOL は、入力80桁をレコードとする場合が多かったと思います。(最新は知らない) 実際の入力があろうが無かろうが、80桁(要するにカードイメージ) 出力は、136桁。特定書式の入出力が容易ですね。C言語及び、その系列は、その外側。 古い記憶ですが。
yumetodo

2018/09/04 12:28

まあGNUのコーディング規約も同様に80ですね。その昔80文字しか表示できないモニターがあってそれに合わせてる
guest

0

1.外れません。1文字読み込むか書き込むだけ。
2.しなければならない、のではなく、そうなっているってことですね
3.そのとおり

投稿2018/09/03 13:08

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cadet_study

2018/09/03 14:54

y_waiwai さん,回答して下さりありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問