質問

I know that the function fseek() can be used to output data to a specific location in a file. But I was wondering if I use fseek() to move to the middle of the file and then output data. Would the new data overwrite the old data? For example if I had a file containing 123456789 and I used fseek() to output newdata after the 5 would the file contain 12345newdata6789 or would it contain 12345newdata.

役に立ちましたか?

解決 2

Yes it lets you do that, and those files are called "Random Access Files". Imagine you have already a set file ( with the structure but empty ), in that case you can fill the "slots" you want, or in the case the slot is filled with data you can overwrite on it.

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 );
}

This is how it works (picture obtained from Deitel-How to program in C 6th Edition):

Deitel-How to program in C 6th Edition

他のヒント

Writing data in the "middle" of a file will overwrite existing data. So you would have '12345newdata'.


EDIT: As mentioned in the comments below, it should be noted that this overwrites data without truncating the rest of the file. As an extended version of your example, if you wrote newdata after the 5 in a file containing 1234567890ABCDEFG, you would then have 12345newdataCDEFG, not 12345newdata.

You probably know this but fseek() merely moves the associated position indicator and doesn't dictate per se whether the proceeding output function will overwrite or insert.

You're probably using fwrite() or some other plain vanilla output function, and these will overwrite, giving you "12345newdata" instead of the inserted variant.

On the other hand, you could roll your own inserting function (I don't think there's a stock stdio.h function for this), and call this after fseek() to get your desired insertion.

Something like this could suffice:

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;
    }
}

(Error handling on fread() and fwrite() left out for verbosity.)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top