「C ファイル入出力」の版間の差分

提供:yonewiki
(ページの作成:「C++へ戻る <table class="mbox-small" style="border:1px solid #aaa; background-color:#f9f9f9; width:22em;" id="RealTitleBanner"> <tr> <td style="width:1px;"></td> <td class="mbox-text plainlist" style="">本来の表記は「<b><span id="RealTitle" style="font-size:large;">C ファイル入出力</span></b>」です。この記事に付けられた題名は{{記事名の制約}}から不正確なものとなっています。…」)
 
12行目: 12行目:
<br />
<br />
== '''ファイル入出力''' ==
== '''ファイル入出力''' ==
 ファイルに文字を読み込んだり書き込んだりする命令です。標準入出力でコンソールに文字を表示させたり、文字入力から値を読み取ったりできましたが、ファイルには全て文字として書き込みます。そして値の読み込みも文字ですが、文字の中でも数字だけで構成されている部分を数値として認識したりするのはプログラム側で工夫することになっています。ファイルの概念があるOSなら使えるようになっているはずの命令です。ファイルのパス名や特定パス名が特別なモノを意味していることもあります。そのあたりはOS独自のものとして、特別に準備がされています。
 基本的な入出力のやりかたは、他のウェブページでも紹介されているので、ここでは、まずワイド文字列の出力について触れておきます。
 ファイル出力用の命令はいくつかありますが、英文字の1バイト文字の範囲であればfprintfが便利です。printfの機能をそのまま、ファイル出力に使えて、変数の出力形式が豊富に設定できるのも良いところです。printfと違って引数が3つの区分になっているのが大きな違いです。ひとつ増えたのはファイルポインタという引数です。このポインタがファイル出力の操作を制御します。通常はなんらかのファイルオープン命令の後からファイルの出力開始位置をさししめしています。
 ファイルオープン命令は以下のようなものです。
<Syntaxhighlight lang="c++">
FILE* pFILE_file;
pFILE_file = open("C:\Directory\fileName.txt", "w");
</Syntaxhighlight>
 上記のようなものです。このようにしたとき変数 pFILE_file をファイルポインタと称しています。open関数は第一引数にパス名を持ちます。日本語のような2バイト文字を含む場合はリテラル(ダブルクォーテンションで挟んだパス名の部分のような文字列)の先頭に、大文字のLをつけます。
<Syntaxhighlight lang="c++">
FILE* pFILE_file;
pFILE_file = open(L"C:\ディレクトリ\ファイル名.txt", "w");
</Syntaxhighlight>
 このような文字列の使い方は文字列操作や日本語文字列の記事で触れています。記事の内容に従えば、もちろん _T も使えます。このように日本語ような2バイト文字を扱うときは、wchar_t型やL""といった決まりを常に意識する必要があります。それがファイル入出力であっても同じだということです。日本語を扱っていても日本語2バイトを意識しないでも大丈夫な命令もちょくちょく出てくるので忘れやすいのかもしれません。例えばファイルを使い終わったらファイルを閉じる必要があります。その命令が以下です。
<Syntaxhighlight lang="c++">
flose(pFILE_file);
</Syntaxhighlight>
 というように日本語を意識することなく閉じるときは、まったくに2バイト文字を意識する必要のない引数だけなので、1バイト文字だけのときと全く同じになります。気を付けてください。ちなみにファイルポインタと呼んでいるpFILE_fileという文字は自分で勝手に名付けたものなので、自由な変数名を付けることができます。変数の名称の制約に違反していない範囲です。
 ここで変数名の先頭にpをつけている理由とかは違う記事で説明しました。大変ですが、記事をイチカラ読み直すと良いでしょう。名前は一度決めたら全部同じにしておく必要があります。毎回違う名前の変数でオープンしたり、クローズしたりするのはファイルポインタがことなっていて一貫性のないことになってしまいます。もちろん入出力を行うときも同じ名前の変数名を使うことになります。ことなる一連のオープンクローズ処理グループであれば違う名前のファイルポインタ名を使うことは問題になりません。
 ファイルオープンのオープン関数の第二引数に使える "w" のようなものはファイルの扱いを決める記号みたいな役割です。 w は新規作成書き込みという意味です。ファイルが既に存在していても、上書きして新規作成します。もとにあったファイルは消えてしまいます。すでにあるファイルに対しての操作に注意が必要です。広く配布する場合には、ファイルを消すことになるけど大丈夫か?ユーザーに再確認するくらいの形式になっている必要があります。たまたまそこにユーザが大事にしているファイルがあったとしたら大問題に発展します。 r は読み取り専用 aは追記。のように意味がつけられています。詳しくは以下の通りです。
 そして、いよいよ本題ですが、UTF16の2バイト文字を書き込むときは fwprintf という関数を使います。たとえば、pwcStringArr という文字列配列に"テスト文字列"\0 のような設定がしてある場合以下のような命令文になります。2バイト文字といっていますが、ShiftJISは1バイト文字扱いで出力して問題ない形式です。1バイトづつ読み込んである特定の1バイトがあると次に2バイト目とあわせて日本語を書き出す仕組みです。
pwcStringArr[7] : L'テ', L'ス', L'ト', L'文', L'字', L'列', '\0'
<Syntaxhighlight lang="c++">
fwprintf(pFILE_file, L"文字列 = %ls", pwcStringArr);
</Syntaxhighlight>
 いわゆるフォーマット指定子が珍しいものに感じる人もいるでしょう。%lsと指定した部分がフォーマット指定子というものです。この指定で2バイト文字が出力できます。あとは、書き出す文字コードがなにかです。ここはファイルオープンされたときのコードに変換するように書き出されます。以下のようにするとUTF-8で書き出されます。UTF-16はサロゲートペアのような大きなコードが割り当てられている特殊な範囲でなければ、一文字が常に2バイトになります。1バイト文字の範囲の文字も2バイトです。UTF-8は1バイト文字は1バイトのまま、サロゲートペアでない範囲の特定の2バイト文字は3バイトになります。
<Syntaxhighlight lang="c++">
FILE* pFILE_file;
pFILE_file = open(L"C:\ディレクトリ\ファイル名.txt", "w, ccs=UTF-8");
</Syntaxhighlight>
 テキストファイルで、UTF-16を使うことは滅多にありません。

2022年10月17日 (月) 14:03時点における版

C++へ戻る


本来の表記は「C ファイル入出力」です。この記事に付けられた題名はテンプレート:記事名の制約から不正確なものとなっています。

※このページではC言語にも存在していたという意味で記事タイトルがC -> ファイル入出力になっていますが、
C++でも同様です。C++だけの機能がある場合は明記します。

ファイル入出力

 ファイルに文字を読み込んだり書き込んだりする命令です。標準入出力でコンソールに文字を表示させたり、文字入力から値を読み取ったりできましたが、ファイルには全て文字として書き込みます。そして値の読み込みも文字ですが、文字の中でも数字だけで構成されている部分を数値として認識したりするのはプログラム側で工夫することになっています。ファイルの概念があるOSなら使えるようになっているはずの命令です。ファイルのパス名や特定パス名が特別なモノを意味していることもあります。そのあたりはOS独自のものとして、特別に準備がされています。


 基本的な入出力のやりかたは、他のウェブページでも紹介されているので、ここでは、まずワイド文字列の出力について触れておきます。


 ファイル出力用の命令はいくつかありますが、英文字の1バイト文字の範囲であればfprintfが便利です。printfの機能をそのまま、ファイル出力に使えて、変数の出力形式が豊富に設定できるのも良いところです。printfと違って引数が3つの区分になっているのが大きな違いです。ひとつ増えたのはファイルポインタという引数です。このポインタがファイル出力の操作を制御します。通常はなんらかのファイルオープン命令の後からファイルの出力開始位置をさししめしています。


 ファイルオープン命令は以下のようなものです。

FILE* pFILE_file;
pFILE_file = open("C:\Directory\fileName.txt", "w");


 上記のようなものです。このようにしたとき変数 pFILE_file をファイルポインタと称しています。open関数は第一引数にパス名を持ちます。日本語のような2バイト文字を含む場合はリテラル(ダブルクォーテンションで挟んだパス名の部分のような文字列)の先頭に、大文字のLをつけます。

FILE* pFILE_file;
pFILE_file = open(L"C:\ディレクトリ\ファイル名.txt", "w");


 このような文字列の使い方は文字列操作や日本語文字列の記事で触れています。記事の内容に従えば、もちろん _T も使えます。このように日本語ような2バイト文字を扱うときは、wchar_t型やL""といった決まりを常に意識する必要があります。それがファイル入出力であっても同じだということです。日本語を扱っていても日本語2バイトを意識しないでも大丈夫な命令もちょくちょく出てくるので忘れやすいのかもしれません。例えばファイルを使い終わったらファイルを閉じる必要があります。その命令が以下です。


flose(pFILE_file);


 というように日本語を意識することなく閉じるときは、まったくに2バイト文字を意識する必要のない引数だけなので、1バイト文字だけのときと全く同じになります。気を付けてください。ちなみにファイルポインタと呼んでいるpFILE_fileという文字は自分で勝手に名付けたものなので、自由な変数名を付けることができます。変数の名称の制約に違反していない範囲です。


 ここで変数名の先頭にpをつけている理由とかは違う記事で説明しました。大変ですが、記事をイチカラ読み直すと良いでしょう。名前は一度決めたら全部同じにしておく必要があります。毎回違う名前の変数でオープンしたり、クローズしたりするのはファイルポインタがことなっていて一貫性のないことになってしまいます。もちろん入出力を行うときも同じ名前の変数名を使うことになります。ことなる一連のオープンクローズ処理グループであれば違う名前のファイルポインタ名を使うことは問題になりません。


 ファイルオープンのオープン関数の第二引数に使える "w" のようなものはファイルの扱いを決める記号みたいな役割です。 w は新規作成書き込みという意味です。ファイルが既に存在していても、上書きして新規作成します。もとにあったファイルは消えてしまいます。すでにあるファイルに対しての操作に注意が必要です。広く配布する場合には、ファイルを消すことになるけど大丈夫か?ユーザーに再確認するくらいの形式になっている必要があります。たまたまそこにユーザが大事にしているファイルがあったとしたら大問題に発展します。 r は読み取り専用 aは追記。のように意味がつけられています。詳しくは以下の通りです。


 そして、いよいよ本題ですが、UTF16の2バイト文字を書き込むときは fwprintf という関数を使います。たとえば、pwcStringArr という文字列配列に"テスト文字列"\0 のような設定がしてある場合以下のような命令文になります。2バイト文字といっていますが、ShiftJISは1バイト文字扱いで出力して問題ない形式です。1バイトづつ読み込んである特定の1バイトがあると次に2バイト目とあわせて日本語を書き出す仕組みです。

pwcStringArr[7] : L'テ', L'ス', L'ト', L'文', L'字', L'列', '\0'


fwprintf(pFILE_file, L"文字列 = %ls", pwcStringArr);


 いわゆるフォーマット指定子が珍しいものに感じる人もいるでしょう。%lsと指定した部分がフォーマット指定子というものです。この指定で2バイト文字が出力できます。あとは、書き出す文字コードがなにかです。ここはファイルオープンされたときのコードに変換するように書き出されます。以下のようにするとUTF-8で書き出されます。UTF-16はサロゲートペアのような大きなコードが割り当てられている特殊な範囲でなければ、一文字が常に2バイトになります。1バイト文字の範囲の文字も2バイトです。UTF-8は1バイト文字は1バイトのまま、サロゲートペアでない範囲の特定の2バイト文字は3バイトになります。


FILE* pFILE_file;
pFILE_file = open(L"C:\ディレクトリ\ファイル名.txt", "w, ccs=UTF-8");


 テキストファイルで、UTF-16を使うことは滅多にありません。