ファイルの操作手順 c. ファイルからデータを入力し、ファイルに出力します。 バイナリ ファイルの読み取りと書き込み

04.09.2023

この記事では、C プログラムでファイルからデータを読み取り、ファイルに情報を書き込む方法を学びます。 C のファイル C プログラムの結果を保存し、プログラムを再起動するときに使用します。 たとえば、計算結果やゲームの統計情報を保存できます。
C でファイルを操作するには、stdio.h ライブラリをインクルードする必要があります。
#含む
一緒に働くには Cのファイル例に従ってファイルへのポインタを指定する必要があります
FILE *ファイルポインタ名;
例えば
ファイル *fin;
ファイルへの fin ポインターを指定します
次に、ファイルを開いてファイル ポインターにリンクする必要があります。 C でファイルを開いて読み取るには、次のコマンドを使用します。
ファイルポインタ名= fopen("ファイルパス", "r");
たとえば次のコマンド
fin = fopen("C:\\Users\\user\\Desktop\\data.txt", "r");
デスクトップ上のパス C:\\Users\\user\\Desktop にあるファイル data.txt が開きます。 ファイルへのパスを確認するには、マウスでファイルを選択し、マウスの右ボタンをクリックします。をクリックしてファイルのプロパティを選択します。 「場所」セクションには、ファイルへのパスが表示されます。 C では、パスは 2 つのスラッシュを使用して示されることに注意してください。
C でファイルを操作した後、次のコマンドを使用してファイルを閉じる必要があります。
fclose(ファイルポインタ名)

C でテキスト ファイルから情報を読み取る

ファイルからロシア語の文字を読み取れるようにするには、次のコマンドを使用してキリル文字を使用するように設定する必要があります。
setlocale(LC_ALL, "ロシア語");

この場合、プログラムの先頭に #include を含める必要があります。

fscanf() 演算子

からの言葉を読むには Cのファイル fscanf()コマンドを使用します。 このコマンドはキーボードから情報を入力するコマンドに似ていますが、最初のパラメータのみがファイルへのポインタです。
fscanf(ファイルポインタ,"%データ入力形式1%データ入力形式2...",&variable1,&variable2...);
たとえば、コマンド
fscanf(fin,"%d%d%d",&a,&b,&c);
ファイル ポインター fin にリンクされているファイルから 3 つの整数変数の文字列を読み取ります。
から読み取るプログラムの例を見てみましょう。 テキストファイル data.txt には 3 列の数字情報が含まれており、配列に書き込まれます。 情報の各列には独自の配列があります。 についての詳細。
#含む
#含む
主要()
(int a;
int b;
int c;
int i;
// ファイルへのポインタを定義します
ファイル *fin;
// 読み取り用にファイルを開きます
fin = fopen("C:\\Users\\user\\Desktop\\data.txt", "r");
// ファイルから 1 行ずつ読み取ります
for (i=0;i<3;i++)
{
// 3 つのファイル値から文字列を読み取り、配列に書き込みます
fscanf(fin,"%d%d%d",&a[i],&b[i],&c[i]);
}
// 配列を画面上に表示します
for (i=0;i<3;i++)
{
printf("%d %d %d ",a[i],b[i],c[i]);
}
getch();
// ファイルを閉じる
fclose(fin);
}

関数 fgets () 内のファイルからの情報の行ごとの読み取り。

fscanf() 演算子はファイルから単語を読み取ります。 最初に出会った空間へ。
C でファイルから行全体を読み取るには、次の構造を使用します。
if (NULL != fgets (文字列変数、文字列長、ファイルポインタ))
{
行を読むときのアクション
}

たとえば、ファイルから 2 行を読み取って画面に表示する C プログラムの場合
#含む
#含む
#含む
主要()
{
// 文字列変数を設定します
文字st1;
文字st2;
// ファイルへのポインタを定義します
ファイル *fin;
// キリル文字を使用した作業を設定します
setlocale(LC_ALL, "ロシア語");
// 読み取り用にファイルを開きます
fin = fopen("C:\\data.txt", "r");
// ファイルから最初の行を読み取ります
if (NULL != fgets (st1, 100, fin))
{
// 文字列を画面に表示します
printf("%s ",st1);)
// ファイルから 2 行目を読み取ります
if (NULL != fgets (st2, 100, fin))
{
// 文字列を画面に表示します
printf("%s ",st2);)
// 読み取りのためにファイルを閉じます
fclose(fin);
}

C でテキスト ファイルに情報を書き込む

データを記録するには C のファイルに、ファイルを録音モードで開く必要があります
ファイルポインタ名= fopen("ファイルパス", "w");
テキスト ファイルの行に書き込むには、fprnitf() コマンドを使用します。これは C のコマンドに似ていますが、最初のパラメーターのみがファイルへのポインターです。
fprintf (ファイルポインタ名,"%入力形式",変数);
たとえば、変数 a の値をファイル out.txt に書き込みます。
a=10;
fout = fopen("C:\\Users\\user\\Desktop\\out.txt", "w");
fprintf(fout,"%d", a);

2 つの数値を要求し、これらの数値の両方とその合計をファイル out.txt に書き込む C プログラムの例

#含む
#含む

主要()
(int a;
int b;
int c;
ファイル *fout;
fout = fopen("C:\\Users\\user\\Desktop\\out.txt", "w");
printf("最初の数字を入力してください");
scanf("%d", &a);
printf("2 番目の数値を入力してください");
scanf("%d", &b);
c=a+b;
fprintf(fout,"%d %d %d",a,b,c);
getch();
fclose(fout);
}

アクセスを容易にするために、ストレージ デバイス内の情報はファイルの形式で保存されます。

ファイルは、データの配列を保存するために割り当てられた外部メモリの名前付き領域です。 ファイルに含まれるデータは非常に多様な性質を持っています。アルゴリズムまたは機械語のプログラム。 プログラム動作またはプログラム実行結果の初期データ。 フリーテキスト。 グラフィック画像など

ディレクトリ (フォルダー、ディレクトリ) - サブディレクトリとファイルの名前を含むストレージ メディア上の名前付きバイトのコレクション。ファイルの編成を簡素化するためにファイル システムで使用されます。

ファイルシステムファイルに対する操作を実行するオペレーティング システムの機能部分と呼ばれます。 ファイル システムの例としては、FAT (FAT – ファイル アロケーション テーブル)、NTFS、UDF (CD で使用される) があります。

FAT には、FAT12、FAT16、および FAT32 の 3 つの主要なバージョンがあります。 それらは、ディスク構造内のレコードのビット深度が異なります。つまり、 クラスター番号を格納するために割り当てられたビット数。 FAT12 は主にフロッピー ディスク (最大 4 KB) に使用され、FAT16 – 小容量ディスクに使用され、FAT32 – 大容量フラッシュ ドライブ (最大 32 GB) に使用されます。

FAT32を例にしてファイルシステムの構造を見てみましょう。

FAT32 ファイル構造

FAT32 システムの外部メモリ デバイスには、バイト アドレス指定ではなくブロック アドレス指定があります。 情報はブロックまたはセクター単位で外部メモリ デバイスに書き込まれます。

セクターは、外部ストレージ デバイス上の情報ストレージのアドレス指定可能な最小単位です。 通常、セクター サイズは 512 バイトに固定されています。 外部メモリ デバイスのアドレス空間を増やすために、セクタはクラスタと呼ばれるグループに結合されます。

クラスターはいくつかのセクターの結合であり、特定の特性を持つ独立した単位と考えることができます。 クラスターの主なプロパティはそのサイズであり、セクター数またはバイト数で測定されます。

FAT32 ファイルシステムは次のような構造になっています。

ファイルの書き込みに使用されるクラスターには 2 から始まる番号が付けられます。原則として、クラスター 2 はルート ディレクトリによって使用され、クラスター 3 からはデータ配列が格納されます。 ルート ディレクトリより上の情報を保存するために使用されるセクターはクラスター化されていません。
ディスク上に必要な最小ファイル サイズは、1 クラスターに相当します。

ブート セクターは次の情報で始まります。

  • EB 58 90 – 無条件ジャンプと署名。
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 – セクター内のバイト数 (通常は 512)。
  • 1 バイト – クラスター内のセクターの数。
  • 2 バイト – 予約セクターの数。

さらに、ブート セクターには次の重要な情報が含まれています。

  • 0x10 (1 バイト) – FAT テーブルの数 (通常は 2)。
  • 0x20 (4 バイト) – ディスク上のセクター数。
  • 0x2С (4 バイト) – ルート ディレクトリのクラスタ番号。
  • 0x47 (11 バイト) – ボリューム ラベル。
  • 0x1FE (2 バイト) – ブート セクター署名 (55 AA)。

ファイル システム情報セクターには次のものが含まれます。

  • 0x00 (4 バイト) – 署名 (52 52 61 41);
  • 0x1E4 (4 バイト) – 署名 (72 72 41 61);
  • 0x1E8 (4 バイト) – 空きクラスターの数、不明な場合は -1。
  • 0x1EC (4 バイト) – 最後に記録されたクラスターの番号。
  • 0x1FE (2 バイト) – 署名 (55 AA)。

FAT テーブルには、ディスク上の各クラスターの状態に関する情報が含まれています。 FAT テーブルの下位 2 バイトには、F8 FF FF 0F FF FF FF FF (物理的に存在しないクラスター 0 および 1 の状態に相当します) が格納されます。 また、各クラスタの状態には、現在のファイルが継続しているクラスタの番号、または以下の情報が含まれます。

  • 00 00 00 00 – クラスターは空きです。
  • FF FF FF 0F – 現在のファイルの終わり。
  • 8バイト - ファイル名。
  • 3バイト - ファイル拡張子。

ルート ディレクトリには、各ファイルに関する次の情報を含む 32 ビット情報レコードのセットが含まれています。

長いファイル名 (ロシア語の名前を含む) を扱う場合、ファイル名は UTF-16 エンコード システムを使用してエンコードされます。 この場合、各文字のエンコードに 2 バイトが割り当てられます。 この場合、ファイル名は次の構造で記述されます。

  • 1 シーケンスバイト。
  • 10 バイトにはファイル名の下位 5 文字が含まれます。
  • 1バイトの属性。
  • 1 バイトが予約されています。
  • 1 バイト – DOS 名のチェックサム。
  • 12 バイトにはファイル名の下 3 文字が含まれます。
  • 2バイト – 最初のクラスターの番号。
  • 長い名前の残りの文字。

C 言語でファイルを操作する

プログラマにとって、開いているファイルは、読み書きされる一連のデータとして表されます。 ファイルを開くと、ファイルが関連付けられます。 I/Oストリーム。 出力情報はストリームに書き込まれ、入力情報はストリームから読み取られます。

ストリームが I/O 用に開かれると、ストリームは stdio.h で定義されている標準の FILE 構造に関連付けられます。 FILE 構造には、ファイルに関する必要な情報が含まれています。

ファイルを開くには fopen() 関数を使用します。この関数は、ファイルに対する後続の操作に使用できる FILE 構造体へのポインタを返します。

FILE *fopen(名前, タイプ);


name - 開くファイルの名前 (パスを含む)、
type は、ファイルへのアクセス方法を定義する文字列へのポインタです。
  • "r" - 読み取り用にファイルを開きます (ファイルは存在する必要があります)。
  • "w" - 書き込みのために空のファイルを開きます。 ファイルが存在する場合、その内容は失われます。
  • "a" - 最後まで書き込むためにファイルを開きます (追加用)。 ファイルが存在しない場合は作成されます。
  • 「r+」 - 読み取りおよび書き込みのためにファイルを開きます (ファイルは存在する必要があります)。
  • 「w+」 - 読み取りと書き込みのために空のファイルを開きます。 ファイルが存在する場合、その内容は失われます。
  • 「a+」 - ファイルを読み取りおよび追加するために開きます。ファイルが存在しない場合は、ファイルが作成されます。

戻り値は、開いているストリームへのポインタです。 エラーが発生した場合は、NULL が返されます。

fclose() 関数は、fopen() 関数を使用して開かれたファイルに関連付けられた 1 つまたは複数のストリームを閉じます。 閉じるストリームは fclose() 関数の引数によって決定されます。

戻り値: ストリームが正常に閉じられた場合は値 0。 エラーが発生した場合は定数 EOF。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#含む
int main() (
ファイル*fp;
文字名 = "my.txt" ;
if ((fp = fopen(name, "r" )) == NULL )
{
printf( 「ファイルを開けませんでした」);
getchar();
0を返します。
}
// ファイルを開くことに成功しました
... // データに対して必要なアクション
fclose(fp);
getchar();
0を返します。
}

ファイルから文字を読み取る:

char fgetc(ストリーム);


関数の引数は、FILE 型のストリームへのポインタです。 この関数は読み取った文字のコードを返します。 ファイルの終わりに達するか、エラーが発生した場合は、定数 EOF が返されます。

シンボルをファイルに書き込む:

fputc(char, ストリーム);

この関数の引数は、文字と、FILE 型のストリームへのポインタです。 読み取った文字のコードを返します。

fscanf() 関数と fprintf() 関数は scanf() 関数と printf() 関数に似ていますが、データ ファイルを操作し、最初の引数としてファイル ポインタを持ちます。

fscanf(ストリーム, "入力フォーマット", 引数);

ほとんどのコンピューター プログラムはファイルを操作するため、ファイルを作成、削除、書き込み、読み取り、開く必要があります。 ファイルとは何ですか? ファイルは、ストレージ デバイスに保存できる名前付きのバイトのセットです。 さて、ファイルとは、file.txt など、独自の一意の名前を持つ特定のバイトのシーケンスを意味することは明らかです。 同じ名前のファイルを同じディレクトリに配置することはできません。 ファイル名は、名前だけでなく拡張子も指します (例: file.txt および file.dat)。 同じ名前ですが、異なるファイルです。 完全なファイル名というものがあります。これは、ファイル名を示すファイル ディレクトリへの完全なアドレスです (例: D:\docs\file.txt)。 これらの基本概念を理解することが重要です。理解していないと、ファイルの操作が困難になります。

ファイルを操作するには、ヘッダー ファイルをインクルードする必要があります . いくつかのクラスが定義され、ヘッダー ファイルがインクルードされます ファイル入力と ファイル出力。

ファイル I/O は標準 I/O に似ていますが、唯一の違いは、I/O が画面ではなくファイルに対して実行されることです。 標準デバイスへの I/O が cin および cout オブジェクトを使用して実行される場合、ファイル I/O を整理するには、cin および cout 演算子と同様に使用できる独自のオブジェクトを作成するだけで十分です。

たとえば、テキスト ファイルを作成し、そのファイルに「Working with files in C++」という行を書き込む必要があります。 これを行うには、次の手順を実行する必要があります。

  1. クラス ofstream のオブジェクトを作成する ;
  2. クラスオブジェクトを書き込み先のファイルに関連付けます。
  3. ファイルに行を書き込みます。
  4. ファイルを閉じます。

ifstream オブジェクトではなく ofstream オブジェクトを作成する必要があるのはなぜですか? ファイルに書き込む必要があり、ファイルからデータを読み取る必要がある場合は、ifstream クラス オブジェクトが作成されるためです。

// stream /*オブジェクト名*/のファイルに書き込むためのオブジェクトを作成します。 //stream クラスのオブジェクト

オブジェクトを fout と呼びます。これが得られるものです。

オフストリーム 4;

なぜオブジェクトが必要なのでしょうか? オブジェクトはファイルに書き込むことができる必要があります。 オブジェクトはすでに作成されていますが、文字列を書き込む必要があるファイルに関連付けられていません。

Fout.open("cppstudio.txt"); // オブジェクトをファイルに関連付けます

ドット操作を通じて、open() クラス メソッドにアクセスし、括弧内にファイル名を示します。 指定されたファイルは、プログラムとともに現在のディレクトリに作成されます。 同名のファイルが存在する場合は、既存のファイルが新しいファイルに置き換えられます。 これでファイルは開いたので、あとは必要な行をファイルに書き込むだけです。 これは次のように行われます。

フォート<< "Работа с файлами в С++"; // запись строки в файл

ストリーム操作を fout オブジェクトと組み合わせて使用​​すると、文字列 Working with files in C++ がファイルに書き込まれます。 ファイルの内容を変更する必要がなくなったので、ファイルを閉じる必要があります。つまり、オブジェクトをファイルから分離する必要があります。

Fout.close(); // ファイルを閉じます

結果 - 「Working with files in C++」という行を含むファイルが作成されました。

ステップ 1 と 2 は組み合わせることができます。つまり、1 行でオブジェクトを作成し、それをファイルに関連付けます。 これは次のように行われます。

オフストリーム fout("cppstudio.txt"); // クラス ofstream のオブジェクトを作成し、それを cppstudio.txt ファイルに関連付けます

すべてのコードを結合して、次のプログラムを取得しましょう。

// file.cpp: コンソール アプリケーションのエントリ ポイントを定義します。 #include "stdafx.h" #include 名前空間 std を使用します。 int main(int argc, char* argv) ( ofstream fout("cppstudio.txt"); // 記録用に ofstream クラスのオブジェクトを作成し、それをファイル cppstudio.txt fout に関連付けます<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

プログラムが正しく動作していることを確認する必要があり、これを行うには、ファイルを開きます cppstudio.txt その内容を見ると、次のようになっているはずです - C++ でファイルを操作します。

  1. ifstream クラスのオブジェクトを作成し、それを読み取りが実行されるファイルに関連付けます。
  2. ファイルを読み取ります。
  3. ファイルを閉じます。
// file_read.cpp: コンソール アプリケーションのエントリ ポイントを定義します。 #include "stdafx.h" #include #含む 名前空間 std を使用します。 int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // キリル文字の正しい表示 buff; // ファイルから読み取られたテキストの中間ストレージ用のバッファ ifstream fin("cppstudio.txt") ; // 読み取るためにファイルを開きました fin >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

このプログラムは、ファイルから読み取る 2 つの方法を示しています。1 つ目はストリームへの転送操作を使用する方法、2 つ目は関数を使用する方法です。 getline() 。 最初のケースでは最初の単語のみが読み取られ、2 番目のケースでは 50 文字の長さの文字列が読み取られます。 ただし、ファイルには 50 文字未満が残っているため、最後の文字までが読み取られます。 2回目以降の閲覧にはご注意ください(17行目) 最初の単語が読み取られたため、最初からではなく、最初の単語の後に続きます。14行目。 プログラムの結果を図 1 に示します。

C++ でのファイルの操作 続行するには、任意のキーを押してください。 。 。

図 1 - C++ でのファイルの操作

プログラムは正しく動作しましたが、コードがすべて正しい場合でも、常にこのようなことが起こるとは限りません。 たとえば、存在しないファイルの名前がプログラムに渡されたか、名前にエラーがありました。 じゃあ何? この場合、何も起こりません。 ファイルが見つからないため、読み取ることができません。 したがって、コンパイラは、ファイル上で作業が行われた行を無視します。 その結果、プログラムは正常に終了しますが、画面には何も表示されません。 これはそのような状況に対する完全に正常な反応であるように思われます。 しかし、単純なユーザーには、何が起こっているのか、なぜファイルの行が画面に表示されないのかがわかりません。 したがって、すべてを明確にするために、C++ にはそのような関数 is_open() が用意されています。この関数は整数値を返します。ファイルが正常に開かれた場合は 1、ファイルが開かれなかった場合は 0 を返します。 ファイルが開かれていない場合に、対応するメッセージが表示されるように、ファイルを開くプログラムを変更してみましょう。

// file_read.cpp: コンソール アプリケーションのエントリ ポイントを定義します。 #include "stdafx.h" #include #含む 名前空間 std を使用します。 int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // キリル文字の正しい表示 buff; // ファイルから読み取られたテキストの中間ストレージ用のバッファ ifstream fin("cppstudio.doc") ; // (無効なファイル名を入力しました) if (!fin.is_open()) // ファイルが開いていない場合 cout<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >>バフ; // cout ファイルの最初の単語をカウントします<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

プログラムの結果を図 2 に示します。

ファイルを開けません! 続行するには、いずれかのキーを押してください。 。 。

図 2 - C++ でのファイルの操作

図 2 からわかるように、プログラムはファイルを開くことができないことを報告しました。 したがって、プログラムがファイルを操作する場合は、ファイルが存在することが確実な場合でも、この関数 is_open() を使用することをお勧めします。

ファイルを開くモード

ファイルを開くモードによって、ファイルがどのように使用されるかが決まります。 モードを設定するために、ios_base クラスはファイルを開くモードを決定する定数を提供します (表 1 を参照)。

ファイルを開くモードは、オブジェクトの作成時または open() 関数の呼び出し時に直接設定できます。 .

オフストリーム fout("cppstudio.txt", ios_base::app); // ファイルを開いてファイルの末尾に情報を追加します fout.open("cppstudio.txt", ios_base::app); // ファイルを開いてファイルの末尾に情報を追加します

ファイルを開くモードは、ビット単位の論理演算を使用して組み合わせることができます。 または| 例: ios_base::out | ios_base::trunc - ファイルをクリアした後、書き込み用にファイルを開きます。

ofstream クラスのオブジェクトは、ファイルに関連付けられている場合、デフォルトでファイル オープン モード ios_base::out | を含みます。 ios_base::trunc . つまり、ファイルが存在しない場合は作成されます。 ファイルが存在する場合、その内容は削除され、ファイル自体は書き込み可能な状態になります。 ifstream クラスのオブジェクトは、ファイルに関連付けられている場合、デフォルトのファイル オープン モード ios_base::in を持ちます。つまり、ファイルは読み取り専用でオープンされます。 ファイルを開くモードは、読みやすくするためにフラグとも呼ばれます。今後はこの用語を使用します。 表 1 にはすべてのフラグがリストされているわけではありませんが、開始するにはこれらで十分です。

ate フラグと app フラグは説明が非常に似ていることに注意してください。どちらもポインタをファイルの末尾に移動しますが、app フラグはファイルの末尾への書き込みのみを許可し、ate フラグは単にフラグを末尾に移動します。ファイルのどこに書き込むかを制限しません。

sizeof() 操作を使用して、C++ の主要なデータ型の特性を計算し、それらをファイルに書き込むプログラムを開発してみましょう。 仕様:

  1. データ型に割り当てられたバイト数
  2. 特定のデータ型が格納できる最大値。

ファイルへの書き込みは、次の形式で行う必要があります。

/* データ型バイト最大値 bool = 1 255.00 char = 1 255.00 short int = 2 32767.00 unsigned short int = 2 65535.00 int = 4 2147483647.00 unsigned int = 4 4294967295.00 long int = 4 .00 unsigned long int = 4 4294967295.00 浮動小数点数 = 4 2147483647.00 long float = 8 9223372036854775800.00 double = 8 9223372036854775800.00 */

このようなプログラムはこのセクションの前半ですでに開発されていますが、そこではデータ型に関するすべての情報が標準出力デバイスに出力されていたため、情報がファイルに書き込まれるようにプログラムを作り直す必要があります。 これを行うには、現在のファイル情報を事前に切り捨てて、書き込みモードでファイルを開く必要があります( 14行目)。 ファイルが作成され、正常に開かれると (16 ~ 20 行目)、cout ステートメントの代わりに、 22行目 fout オブジェクトを使用します。 したがって、画面の代わりに、データ型に関する情報がファイルに書き込まれます。

// write_file.cpp: コンソール アプリケーションのエントリ ポイントを定義します。 #include "stdafx.h" #include #含む // ファイルを操作する #include // 名前空間 std を使用した入出力マニピュレータ; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // オブジェクトをファイルに関連付け、ファイルを書き込みモードで開き、最初にファイルからすべてのデータを削除します ofstream fout("data_types.txt ", ios_base::out | ios_base::trunc); if (!fout.is_open()) // ファイルが開かれていない場合 ( cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // 列ヘッダー <<"bool = " << sizeof(bool) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных bool*/ << (pow(2,sizeof(bool) * 8.0) - 1) << endl << "char = " << sizeof(char) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных char*/ << (pow(2,sizeof(char) * 8.0) - 1) << endl << "short int = " << sizeof(short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных short int*/ << (pow(2,sizeof(short int) * 8.0 - 1) - 1) << endl << "unsigned short int = " << sizeof(unsigned short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned short int*/ << (pow(2,sizeof(unsigned short int) * 8.0) - 1) << endl << "int = " << sizeof(int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных int*/ << (pow(2,sizeof(int) * 8.0 - 1) - 1) << endl << "unsigned int = " << sizeof(unsigned int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned int*/ << (pow(2,sizeof(unsigned int) * 8.0) - 1) << endl << "long int = " << sizeof(long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long int*/ << (pow(2,sizeof(long int) * 8.0 - 1) - 1) << endl << "unsigned long int = " << sizeof(unsigned long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных undigned long int*/ << (pow(2,sizeof(unsigned long int) * 8.0) - 1) << endl << "float = " << sizeof(float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных float*/ << (pow(2,sizeof(float) * 8.0 - 1) - 1) << endl << "long float = " << sizeof(long float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long float*/ << (pow(2,sizeof(long float) * 8.0 - 1) - 1) << endl << "double = " << sizeof(double) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных double*/ << (pow(2,sizeof(double) * 8.0 - 1) - 1) << endl; fout.close(); // программа больше не использует файл, поэтому его нужно закрыть cout << "Данные успешно записаны в файл data_types.txt\n"; system("pause"); return 0; }

標準入出力とファイル入出力がまったく同じように使用されているため、プログラムの変更は最小限であることに気付かないわけがありません。 番組の最後には、45行目ファイルを明示的に閉じましたが、これは必須ではありませんが、良いプログラミング方法であると考えられています。 標準入出力のフォーマットに使用されるすべての関数とマニピュレータは、ファイル入出力にも関連していることに注意してください。 したがって、ステートメントを実行してもエラーは発生しませんでした。コート オブジェクトに置き換えられました四。

ファイルを使用すると、ユーザーはキーボードからデータを入力することなく、大量のデータをディスクから直接読み取ることができます。 ファイルには主に 2 つのタイプがあります。 テキストとバイナリ.

文章任意の文字で構成されるファイルが呼び出されます。 これらは行にまとめられており、各行は「」で終わります。 行末」。 ファイル自体の終わりは記号「」で示されます。 ファイルの終わり」。 情報をテキスト ファイルに書き込むと、テキスト ファイルは任意のテキスト エディタを使用して表示できます。すべてのデータは文字タイプに変換され、文字形式で保存されます。

バイナリファイルでは、情報は特定のサイズのブロックの形式で読み書きされ、そこには任意のタイプおよび構造のデータを保存できます。

ファイルを操作するには、と呼ばれる特別なデータ型が必要です。 ストリーム。流れ イフストリーム読み取りモードでファイルを操作するために使用されます。 川下録音モード中。 書き込みモードと読み取りモードの両方でファイルを操作するには、ストリームが使用されます fストリーム.

C++ プログラムでテキスト ファイルを操作する場合は、ライブラリをインクルードする必要があります。 iostreamそして fストリーム.

データをテキスト ファイルに書き込むには、次のことを行う必要があります。

  1. 型変数を記述する 川下.
  2. 開ける.
  3. 情報をファイルに出力します。
  4. 必ずファイルを閉じてください。

テキスト ファイルからデータを読み取るには、次のことを行う必要があります。

  1. 型変数を記述する イフストリーム.
  2. 関数を使用してファイルを開く 開ける.
  3. ファイルから情報を読み取る場合、各データを読み取るときに、ファイルの終わりに達したかどうかを確認する必要があります。
  4. ファイルを閉じます。

テキストファイルへの情報の書き込み

前述したように、テキスト ファイルの操作を開始するには、次のような変数を記述する必要があります。 川下。 たとえば、次のようになります。

F の流れ。

変数が作成されます F情報をファイルに書き込みます。 次の段階では、ファイルを書き込み用に開く必要があります。 一般に、ストリーム開始演算子は次のようになります。

F.開ける("ファイル", モード);

ここ F- 次のように記述される変数 川下, ファイル- ディスク上のファイルのフルネーム、 モード- 開かれているファイルを操作するモード。 完全なファイル名を指定する場合は、二重スラッシュを使用する必要があることに注意してください。 たとえばファイルにアクセスするには アカウント.txt、フォルダ内にあります サイト ディスク上 D、プログラムでは次のように指定する必要があります。 D:\\サイト\\ アカウント。TXT.

ファイルは次のいずれかのモードで開くことができます。

  • ios::で- ファイルをデータ読み取りモードで開きます。 mode はスレッドのデフォルトのモードです イフストリーム;
  • ios::out- データ記録モードでファイルを開きます(この場合、既存のファイルに関する情報は破壊されます)。 mode はスレッドのデフォルトのモードです 川下;
  • ios::アプリ- ファイルの末尾にデータを書き込むモードでファイルを開きます。
  • ios::食べた- すでに開いているファイルの末尾に移動します。
  • ios::trunc- ファイルをクリアします。これは ios::out モードでも発生します。
  • ios::nocreate- ファイルが存在しない場合は、ファイルを開く操作を実行しないでください。
  • ios::noreplace- 既存のファイルを開かないでください。

モードパラメータが存在しない場合があります。その場合、ファイルはこのストリームのデフォルトモードで開かれます。

変数でファイルを (任意のモードで) 正常に開いた後 F保存されます 真実、 さもないと 間違い。 これにより、ファイルを開く操作が正しいかどうかを確認できます。

ファイルを開きます (ファイルを例に挙げます) D:\\サイト\\ アカウント。TXT) 録画モードでは、次のいずれかを実行できます。

ファイルを書き込みモードで開くと、情報を書き込むことができる空のファイルが作成されます。

既存のファイルを追加モードで開きたい場合は、値を使用する必要があります。 ios::アプリ.

記録モードでファイルを開いた後は、標準の出力デバイスの代わりにのみ、画面への書き込みと同じ方法でファイルに書き込むことができます。 コート開いているファイルの名前を指定する必要があります。

たとえば、ストリームに書き込むには F変数 あるの場合、出力ステートメントは次のようになります。

F<

ストリームへのシリアル出力の場合 G変数 b, c, d出力ステートメントは次のようになります。

G<

ストリームを閉じるには、次の演算子を使用します。

F.close();

例として、次の問題を考えてみましょう。

問題 1

テキストファイルを作成する D:\\ サイト\\アカウント 。TXTそしてそれに書き込む n実数。

解決

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

#include "stdafx.h"
#含む
#含む
#含む
名前空間 std を使用します。
int main()
{

int i、n;
ダブルa;
// ファイルにデータを書き込むためのストリームを記述します
川の流れf;
// ファイルを書き込みモードで開きます。
//ios::out モードがデフォルトで設定されています
f.open("D: \\サイト\\アカウント.txt"、ios::out ) ;
// 実数の数を入力します
コート<< «n=» ; cin >>n;
//実数を入力するループ
//そしてファイルに書き込みます
for (i= 0 ; i< n; i++ )
{
コート<< «a=» ;
//数値を入力してください
シン>>a;
f<< a<< «\t «;
}
//ストリームを閉じる
f.close();
システム("一時停止");
0 を返します。
}

テキストファイルから情報を読み取る

テキストファイルから情報を読み取るには、次のような変数を記述する必要があります。 イフストリーム。 この後、演算子を使用してファイルを読み取り用に開く必要があります。 開ける。 変数に名前を付ける場合 Fの場合、最初の 2 つの演算子は次のようになります。

ファイルを読み取りモードで開いた後は、キーボードからの場合と同じ方法でファイルから情報を読み取ることができます。 シンデータを読み取るストリームの名前を指定する必要があります。

たとえば、ストリームからデータを読み取るには F変数に入れる ある、入力ステートメントは次のようになります。

F>>a;

テキスト エディターでは、2 つの数値の間にスペース、タブ、行末などの文字が少なくとも 1 つある場合、それらの数値は区切られているとみなされます。 プログラマがテキスト ファイルにどのような値がいくつ保存されているかを事前に知っていると便利です。 ただし、多くの場合、ファイルに保存されている値のタイプのみがわかっており、その数は異なる場合があります。 この問題を解決するには、ファイルから値を 1 つずつ読み取り、読み取る前にファイルの終わりに達したかどうかを確認する必要があります。 そして、関数はこれを行うのに役立ちます F.eof()。 ここ F- スレッド名 この関数はブール値を返します。 真実または 間違い、ファイルの終わりに達したかどうかに応じて。

したがって、ファイル全体の内容を読み取るループは次のように記述できます。

資料をよりよく理解するために、問題を検討してください。

問題 2

テキスト ファイル D:\\game\\accounts.txt には実数が保存され、画面に表示されて数値が計算されます。

解決

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#include "stdafx.h"
#含む
#含む
#含む
#含む
名前空間 std を使用します。
int main()
{
setlocale(LC_ALL, "RUS");
int n= 0 ;
float a;
fストリームF;
// ファイルを読み取りモードで開きます
F.open("D: \\サイト\\アカウント.txt") ;
//ファイルが正しく開かれた場合、
もし(F)
{
// ファイルから値を読み取るループ。 ループの実行は中断されます。
// ファイルの終わりに到達すると、この場合、F.eof() は true を返します。
while (!F.eof())
{
//ストリーム F から次の値を変数 a に読み込みます
F >> a;
//変数aの値を画面に出力する
コート<< a<< «\t «;
//読み込む数値の数を増やす
n++ ;
}
//ストリームを閉じる
F.close();
//読み取った数字の数を画面に入力
コート<< «n=» << n<< endl;
}
// ファイルの開き方が間違っていた場合、出力は
//そのようなファイルが存在しないことに関するメッセージ
それ以外の場合は<< 「ファイルが存在しません」<< endl;
システム("一時停止");
0 を返します。
}

これで、テキスト ファイルに関する比較的広範なレッスンは終了です。 次の記事では、 の処理に使用される操作方法について説明します。

最終更新日: 2015 年 10 月 31 日

System.IO 名前空間内のディレクトリを操作するように設計された 2 つのクラス、Directory と DirectoryInfo があります。

ディレクトリクラス

Directory クラスは、ディレクトリを管理するための静的メソッドを多数提供します。 これらの方法のいくつかは次のとおりです。

    CreateDirectory(path) : 指定されたパスにディレクトリを作成します

    削除(パス) : 指定されたパスのディレクトリを削除します。

    Exists(path) : 指定されたパスにディレクトリが存在するかどうかを判断します。 存在する場合は true が返され、存在しない場合は false が返されます。

    GetDirectories(path) : ディレクトリ パス内のディレクトリのリストを取得します。

    GetFiles(path) : ディレクトリ パス内のファイルのリストを取得します。

    Move(sourceDirName, destDirName): ディレクトリを移動します

    GetParent(path) : 親ディレクトリを取得します。

DirectoryInfoクラス

このクラスは、ディレクトリの作成、削除、移動、その他の操作の機能を提供します。 多くの点で、これは Directory に似ています。 そのプロパティとメソッドの一部は次のとおりです。

    Create() : ディレクトリを作成します

    CreateSubdirectory(path) : 指定されたパスにサブディレクトリを作成します

    Delete() : ディレクトリを削除します

    Exists プロパティ: ディレクトリが存在するかどうかを決定します

    GetDirectories() : ディレクトリのリストを取得します

    GetFiles() : ファイルのリストを取得します

    MoveTo(destDirName) : ディレクトリを移動します

    親プロパティ: 親ディレクトリの取得

    ルートプロパティ: ルートディレクトリの取得

これらのクラスの使用例を見てみましょう

ファイルとサブディレクトリのリストの取得

文字列 dirName = "C:\\"; if (Directory.Exists(dirName)) ( Console.WriteLine("サブディレクトリ:"); string dirs = Directory.GetDirectories(dirName); foreach (dirs 内の文字列 s) ( Console.WriteLine(s); ) Console.WriteLine( ); Console.WriteLine("Files:"); string files = Directory.GetFiles(dirName); (ファイル内の文字列) ( Console.WriteLine(s); )

ファイル名にスラッシュを使用することに注意してください。 二重スラッシュ (「C:\\」) を使用するか、単一のスラッシュを使用しますが、パス全体の前に @ 記号を置きます (@"C:\Program Files")。

ディレクトリの作成

文字列パス = @"C:\SomeDir"; 文字列サブパス = @"プログラム\avalon"; DirectoryInfo dirInfo = 新しい DirectoryInfo(パス); if (!dirInfo.Exists) ( dirInfo.Create(); ) dirInfo.CreateSubdirectory(subpath);

まず、そのようなディレクトリが存在するかどうかを確認します。存在する場合は作成できず、アプリケーションはエラーをスローします。 その結果、次のパスが得られます: "C:\SomeDir\program\avalon"

ディレクトリ情報の取得

文字列 dirName = "C:\\Program Files"; DirectoryInfo dirInfo = 新しい DirectoryInfo(dirName); Console.WriteLine($"ディレクトリ名: (dirInfo.Name)"); Console.WriteLine($"完全なディレクトリ名: (dirInfo.FullName)"); Console.WriteLine($"ディレクトリ作成時間: (dirInfo.CreationTime)"); Console.WriteLine($"Root: (dirInfo.Root)");

ディレクトリの削除

いくつかのファイルまたはサブディレクトリを含む空ではないフォルダーに Delete メソッドを単純に適用すると、アプリケーションはエラーをスローします。 したがって、フォルダーをそのすべての内容とともに削除する必要があることを示す追加のブール型パラメーターを Delete メソッドに渡す必要があります。

文字列 dirName = @"C:\SomeFolder"; try ( DirectoryInfo dirInfo = new DirectoryInfo(dirName); dirInfo.Delete(true); Console.WriteLine("ディレクトリが削除されました"); ) catch (Exception ex) ( Console.WriteLine(ex.Message); )

文字列 dirName = @"C:\SomeFolder"; Directory.Delete(dirName, true);

ディレクトリの移動

文字列 oldPath = @"C:\SomeFolder"; 文字列 newPath = @"C:\SomeDir"; DirectoryInfo dirInfo = 新しい DirectoryInfo(oldPath); if (dirInfo.Exists && Directory.Exists(newPath) == false) ( dirInfo.MoveTo(newPath); )

移動するときは、古いディレクトリのすべての内容を移動する新しいディレクトリが存在してはいけないことを考慮する必要があります。