ググっても出てこなかったのでメモ。
C言語でファイルを1レコード読む場合は、通常はfgetsを使用します。
しかし、fgetsで読み込んだレコードにNUL文字(\0)が含まれる場合、読みこんだ文字列がNUL終端されてしまい、NUL文字以降改行コードまでの文字列を取得できなくなってしまいます。
NUL文字以降の文字列を取得したい場合は、fgetcで1文字ずつ読み込み、NUL文字や改行コードを読みこんだ際の処理を自力で実装する必要があります。
(Linuxのコマンド等でNUL文字を他の文字に置換し中間ファイルに出力し、その中間ファイルをfgetsで読み込んでも良いのですが、余分なファイルIOが発生するので性能がシビアな要件では避けたい実装です)
以下、サンプルコードです。
NUL文字を含むファイルを1レコードずつ読み込み、レコードフォーマットを編集してファイルに出力する処理です。
【サンプルコード】
#include <stdio.h>
#include <stdlib.h>
#define N 1024
/* main */
int main(void) {
FILE *fp1;
FILE *fp2;
char *filename1 = "/home/hoge/in.txt";
char *filename2 = "/home/hoge/out.txt";
char readline[N] = {'\0'};
int ch;
int i;
/* 初期化 */
memset(readline, '\0', sizeof(readline));
i=0;
/* ファイルのオープン */
if ( (fp1 = fopen(filename1, "rb")) == NULL) {
fprintf(stderr, "%sのオープンに失敗しました.\n", filename1);
return 1;
}
if ( (fp2 = fopen(filename2, "wb")) == NULL) {
fprintf(stderr, "%sのオープンに失敗しました.\n", filename2);
return 1;
}
/* ファイルの終端まで文字を1文字ずつ読み取り出力する */
while ( (ch = fgetc(fp1)) != EOF ) {
/* NUL文字を変換(後の処理でNUL終端されるのを避ける) */
if (ch==0){ //NUL文字
ch=44; //カンマ
}
/* 1文字ずつ文字列に書き込み */
readline[i]=(char)ch;
i++;
/* 1レコード読みこんだ場合 */
if (ch==10){ //改行コード(\n)
/* 実際はここでレコードフォーマット編集 */
/* 編集した文字列をファイル出力 */
fprintf(fp2, "%s",readline);
/* 次のレコード読み取りに備え初期化 */
memset(readline, '\0', sizeof(readline));
i=0;
}
}
/* ファイルのクローズ */
fclose(fp1);
fclose(fp2);
return 0;
}