3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援→開発戻り浦島太郎状態の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。

(C++)Win32APIを使ってテキストファイルを開き1行ずつ読み込もうとおもったけど...

年に1,2回ほどしか触らない C++ は相変わらず苦手な3流プログラマです。。

設定が入ってるテキストファイルを開き中身を変更するアプリを作ってるわけですが、早速ファイルオープンのところで詰まりました。

とりあえずWindows向けアプリということで Win32 API で作ります。

POSIX と Windows でのファイルオープン方法 - IT戦記:を参考にさせていただくと、CreateFileA関数を使うといいようです。

参考:

Win32 API でのファイルアクセス

ただ、CreateFileA 関数を使ってファイルの中身を読むにはReadFile関数を使うわけですが、これがファイルポインタを使ってバイト指定でしか読めないんですよね。

今回は行単位に読み込んで処理をしたいので、C言語の標準関数を使って、fopen() → fgets () → fclose()という流れでやることにしました。

しかし、これらの標準関数の使い方ももう忘れてます。(Cの教科書レベルに書いてる内容なんですがね。。)

ということで、ファイル入出力を参考にさせてもらいました。

なお、C標準関数ではファイルの変更できないので、一旦設定ファイルをコピーしてそれを開き中身変更して保存することにしました。

下記は a.txt の中身に「あいうえお」があれば「かきくけこ」に置換するサンプルです。

WCHAR chrSettingFile[1024];

swprintf( chrSettingFile , _T("C:\\a.txt") );

 

WCHAR chrSettingFile_Bkup[1024];

swprintf( chrSettingFile , _T("C:\\a_bk.txt") );

 

if( PathFileExists( chrSettingFile ) ) {

// CheckFileNameは存在した時の処理

printf("%s" , "ファイルあり");

//バックアップファイルコピー

if ( CopyFile( chrSettingFile , chrSettingFile_Bkup , false) == false){

return 1;

}

//ファイルポインタ(読み込み元)

FILE *fp_r;

if (( fp_r = _wfopen( chrSettingFile_Bkup , _T( "r" ) )) == NULL){

printf("%s" , "オープン失敗_bk");

return 1;

}

 

//ファイルポインタ(書き込み先元)

FILE *fp_w;

if (( fp_w = _wfopen( chrSettingFile , _T( "w" ) )) == NULL){

printf("%s" , "オープン失敗");

return 1;

}

 

WCHAR s[1024];

WCHAR setting[1024];

swprintf( setting , _T( "あいうえお" ) );

//1行読み込み

while ( fgetws( s , 1024 ,fp_r) != NULL){

WCHAR row[1024];

if ( wcsstr( s , setting ) != NULL){

// あいうえお があったら かきくけこ に置換する

swprintf( row , _T("かきくけこ\n") );

}else{

swprintf( row , s );

}

 

int ret = fputws( row , fp_w );

if( ret == EOF ) {

printf( "ファイル出力エラー\n" );

return 1;

}

}

fclose( fp_r );

fclose( fp_w );

}