C++の基礎:モダンなC++によるWindowsのファイル操作
概要
CやC++では、多くのファイルを操作する方法があります。C言語では、FILE、fopen()、fclose()、C++言語ではFileOpen()といった操作を行うだけで十分でした。しかしながらモダンなC++では、マルチプラットフォームのOSやグローバル言語、その他の利点を活かして、ファイルストリームを使用した方が、より適切に操作できます。Embarcaderoのdocwikiには「ファイル ストリームの使い方」に関するの良い情報があります。
この記事では、ファイルのread/writeの操作に関するモダンなC++の手法を見てみましょう。
C++でUnicodeStringのリストをファイル(UTF8、UTF16、UTF32)に保存する
デフォルトでUnicodeStringをサポートしているTStringListコンポーネントを使用すれば、あらゆる言語のテキストドキュメントの読み込み/保存が簡単にできます。
UnicodeStringを初めて使用する方は、C++の基礎: WindowsでのUnicodeStringの使い方を学ぶの記事をご覧ください。このSaveおよびLoadメソッドは、多くのコンポーネントのTStringList形式のプロパティ(Memo1-> Lines、ListView1-> Itemsなど)で利用できるため、非常に便利です。
TStringList *strlist = new TStringList;
strlist->Add("Hello");
strlist->Add("How are you?");
...
strlist->SaveToFile(L"D://test.txt");
strlist->SaveToFile(L"D://test2.txt", TEncoding::UTF8);
C++でファイル(UTF8, UTF16, UTF32) からUnicodeStringのリストを読み込む
TStringList *strlist = new TStringList;
strlist->LoadFromFile(L"D://test.txt");
C++でStreamReaderを使用してファイル行を読み込む
モダンなC++では、以下の例のようにTStreamReaderを使用して簡単にテキストファイルを読むことができます。以下のコード例では、各行を UnicodeString に読み込み、"the" word を見つけたときにメッセージを表示しています。
TStreamReader *SReader;
UnicodeString us;
SReader = new TStreamReader(OpenDialog1->FileName, TEncoding::UTF8);
do
{
us=SReader->ReadLine();
if(us.Pos(L"the")) ShowMessage(L"Word found in this line");
} while(!SReader->EndOfStream);
C++でStreamReaderとOpenDialogを使用してファイル行を読み込む
以下のコード例では、OpenDialogコンポーネントを使用してファイルを選択し、すべての行で "the "という単語を検索し、この単語が少なくとも1つある行をカウントします。
TStreamReader *SReader;
UnicodeString us;
int count=0;
OpenDialog1->FileName="";
OpenDialog1->Execute();
if(OpenDialog1->FileName.Length()>0)
{
SReader = new TStreamReader(OpenDialog1->FileName, TEncoding::UTF8);
do
{
us=SReader->ReadLine();
if(us.Pos(L"the")>0) count++;
} while(!SReader->EndOfStream);
}
ShowMessage(IntToStr(count)+L" Lines Found.");
C++でFileStreamを利用したデータファイルの読み込み/書き込み(バイナリ、構造体ブロックなど)
ストリームクラスは全て、データを読み書きするためのメソッドを共有しています。 これらのメソッドは、次の点で区別されています:
- 読み書きしたバイト数を返すかどうか
- バイト数を知る必要があるかどうか
- エラー時に例外を発生させるかどうか
詳しくはEmbarcadero docwikiのストリームを使ってデータの読み書きを行うを参照ください。
#include <vcl.h>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
struct st_dat // let's define a default structure
{
int X, Y;
};
struct st_dat dat; // let's create a structure
//--- WRITE A STRUCTURE BLOCK ---
void write_file(String str)
{
TFileStream* fs;
try
{
fs = new TFileStream(str, fmCreate | fmOpenReadWrite); // Open File Stream
if(fs)
{
fs->Write(&dat, sizeof(dat)); // Write structure block in its size
}
}
__finally
{
fs->Free();
}
}
//--- READ A STRUCTURE BLOCK ---
void read_file(String str)
{
TFileStream* fs;
try
{
fs=new TFileStream(str, fmOpenRead );
if(fs)
{
fs->Read(&dat, sizeof(dat));
}
}
__finally
{
fs->Free();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
dat.X=960; // let's add some data
dat.Y=540;
write_file(L"D:\\test.dat");
read_file(L"D:\\test.dat");
std::cout << dat.X << "," << dat.Y << '\n';
//ShowMessage(sizeof(dat.X));
getchar();
return 0;
}