3

我知道函数 fseek() 可用于将数据输出到文件中的特定位置。但我想知道我是否使用 fseek() 移动到文件中间然后输出数据。新数据会覆盖旧数据吗?例如,如果我有一个包含 123456789 的文件,并且我使用 fseek() 在 5 之后输出 newdata,那么该文件将包含 12345newdata6789 还是包含 12345newdata。

4

3 回答 3

6

在文件的“中间”写入数据将覆盖现有数据。所以你会有'12345newdata'。


编辑:正如下面的评论中提到的,应该注意的是,这会覆盖数据而不截断文件的其余部分。作为您的示例的扩展版本,如果您在包含 的文件中编写newdata了,那么您将拥有,而不是51234567890ABCDEFG12345newdataCDEFG 12345newdata

于 2012-11-17T23:48:22.310 回答
2

是的,它可以让您这样做,这些文件称为“随机访问文件”。假设您已经有一个设置文件(具有结构但为空),在这种情况下,您可以填充所需的“插槽”,或者在插槽充满数据的情况下,您可以覆盖它。

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):

Deitel-如何在 C 第 6 版中编程

于 2012-11-17T23:47:20.500 回答
2

您可能知道这一点,但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()省略。)

于 2012-11-18T02:42:02.470 回答