【发布时间】:2012-11-17 23:46:00
【问题描述】:
我知道函数 fseek() 可用于将数据输出到文件中的特定位置。但我想知道我是否使用 fseek() 移动到文件中间然后输出数据。新数据会覆盖旧数据吗?例如,如果我有一个包含 123456789 的文件,并且我在 5 之后使用 fseek() 输出 newdata,那么该文件将包含 12345newdata6789 还是包含 12345newdata。
【问题讨论】:
我知道函数 fseek() 可用于将数据输出到文件中的特定位置。但我想知道我是否使用 fseek() 移动到文件中间然后输出数据。新数据会覆盖旧数据吗?例如,如果我有一个包含 123456789 的文件,并且我在 5 之后使用 fseek() 输出 newdata,那么该文件将包含 12345newdata6789 还是包含 12345newdata。
【问题讨论】:
在文件的“中间”写入数据会覆盖现有数据。所以你会有'12345newdata'。
1234567890ABCDEFG 的文件中的5 之后写newdata,那么您将拥有12345newdataCDEFG,not 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-How to program in 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() 的错误处理省略了冗长。)
【讨论】: