関数fseek()を使用して、ファイル内の特定の場所にデータを出力できることを知っています。しかし、fseek()を使用してファイルの途中に移動し、データを出力するかどうか疑問に思いました。新しいデータは古いデータを上書きしますか?たとえば、123456789を含むファイルがあり、5の後にfseek()を使用してnewdataを出力した場合、ファイルには12345newdata6789が含まれるか、12345newdataが含まれます。
3 に答える
ファイルの「中央」にデータを書き込むと、既存のデータが上書きされます。したがって、「12345newdata」があります。
編集:以下のコメントで述べられているように、これはファイルの残りの部分を切り捨てずにデータを上書きすることに注意してください。例の拡張バージョンとして、を含むファイル
newdata
の後にを書き込んだ場合、はではなく、になります。5
1234567890ABCDEFG
12345newdataCDEFG
12345newdata
はい、それはあなたにそれを可能にします、そしてそれらのファイルは「ランダムアクセスファイル」と呼ばれます。すでにセットファイル(構造は空です)があると想像してください。その場合は、必要な「スロット」を埋めることができます。スロットがデータで埋められている場合は、上書きできます。
typedef struct{
int number;
char name[ 20 ];
char lastname[ 20 ];
float score;
}students_t;
/* Supposing that you formatted the file already and the file is opened. */
/* Imagine the students are listed each one has a record. */
void modifyScore( FILE * fPtr ){
students_t student = { 0, "", "", 0.0 };
int nrecord;
float nscore;
printf( "Enter the number of the student:" );
scanf( "%d", &record )
printf( "Enter the new Score:" );
scanf( "%f", &nscore ); // this is a seek example so I will not complicate things.
/*Seek the file ( record - 1 ), because the file starts in position 0 but the list starts in 1*/
fseek( fPtr, ( record - 1 ) * sizeof ( students_t ), SEEK_SET );
/* Now you can read and copy the slot */
fread( fPtr, "%d%s%s%f", &student.number, student.name, student.lastname, &student.score );
/* Seek again cause the pointer moved. */
fseek( fPtr, ( record - 1 ) * sizeof ( students_t ), SEEK_SET );
student.score = nscore;
/*Overwrite his information, only the score will be altered. */
fwrite( &student, sizeof( student_t ), 1, fPtr );
}
これがその仕組みです(Deitelから取得した写真-C 6th Editionでのプログラミング方法):
あなたはおそらくこれを知っていますfseek()
が、関連する位置インジケータを動かすだけであり、進行中の出力関数が上書きするか挿入するかをそれ自体は指示しません。
fwrite()
または他の単純なバニラ出力関数を使用している可能性があります。これらは上書きされ、挿入されたバリアントの代わりに「12345newdata」が表示されます。
一方、独自の挿入関数をロールして(このためのストック関数はないと思いますstdio.h
)、後でこれを呼び出してfseek()
、目的の挿入を取得することもできます。
このようなもので十分かもしれません:
insert(const void *ptr, size_t len, FILE *fp) {
char tmp[len];
size_t tmplen;
while (len) {
// save before overwriting
tmplen = fread(tmp, 1, sizeof(tmp), fp);
fseek(fp, -tmplen, SEEK_CUR);
// overwrite
fwrite(ptr, len, 1, fp);
// reloop to output saved data
ptr = tmp;
len = tmplen;
}
}
(エラー処理はオンfread()
でfwrite()
、冗長性のために省略されています。)