rewind和fsetpos是否也可以干预C文件附加模式后续写入?

Unk*_*123 5 c standards file mode append

C11标准N1570工作草案在第306页"7.21.5.3 fopen功能"部分说

打开具有追加模式的文件('a'作为mode参数中的第一个字符)会导致对文件的所有后续写入强制转换为当前的文件结束,而不管是对fseek函数的中间调用....

任何人都可以确认不仅fseek功能而且其他文件定位功能如fsetposrewind都不能干预追加模式吗?

好吧,第338页的标准表示倒带与(void)fseek(stream,0L,SEEK_SET)类似,除了流的错误指示符也被清除.但据我在第337页阅读的标准,该标准没有说明fsetpos类似于fseek.


源代码来说明这个问题

#include <stdio.h>

// Declare the File Pointer
    FILE *fp;

// Declare the test integer variable
    int TEST;

// declare the test position variable for fsetpos test
    fpos_t POSITION;

void WriteData(int choice){
    // Clear the file content
        fp = fopen("test.bin", "wb"); fclose(fp);

    // Reopen the file with ab
        fp = fopen("test.bin", "ab");

    // Initialize the test integer variable
        TEST = 100;

    // Write five sample data
        int i;
        for(i = 1; i <= 5; i++) {

            fwrite(&TEST, sizeof(TEST), 1, fp);

            // If two data were written then save the position
            if( i == 2 ) 
                fgetpos(fp, &POSITION);
        }

    //  Change the data
        TEST = 54321;   

    // Declare the test case
        switch(choice){
            case 1 : fseek(fp, (long) 2*sizeof(TEST), SEEK_SET); break;
            case 2 : rewind(fp); break;
            case 3 : fsetpos(fp, &POSITION); break;
        }

    // Write the data again
        fwrite(&TEST, sizeof(TEST), 1, fp);

    // Close the file
        fclose(fp);
}


void ReadData(){
    // Open the file for read
        fp = fopen("test.bin", "rb");

        printf("\n [OUTPUT]");
    // while the data can be read then print it to the console
        while( fread(&TEST, sizeof(TEST), 1, fp) == 1)
            printf("\n %d", TEST);

    // Close the file
        fclose(fp);
}

int main(){

    /* Test Case Process */
        printf("\n\n Intervene using fseek(fp, (long) 2*sizeof(TEST), SEEK_SET);");
        WriteData(1);
        ReadData();

        printf("\n\n Intervene using rewind(fp);");
        WriteData(2);
        ReadData();

        printf("\n\n Intervene using fsetpos(fp, &POSITION);");
        WriteData(3);
        ReadData();




    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所需的输出:

 Intervene using fseek(fp, (long) 2*sizeof(TEST), SEEK_SET);
 [OUTPUT]
 100
 100
 100
 100
 100
 54321

 Intervene using rewind(fp);
 [OUTPUT]
 100
 100
 100
 100
 100
 54321

 Intervene using fsetpos(fp, &POSITION);
 [OUTPUT]
 100
 100
 100
 100
 100
 54321
Run Code Online (Sandbox Code Playgroud)

如果输出是这样的,那么标准确实不仅确认了不能干预后续写入的fseek功能,还确认了倒带fsetpos.否则,如果输出不是那样,那么标准不会证实它.

我在Windows 10上使用tdm-gcc 4.9.2和Ubuntu 16.04 gcc 5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.4)进行了测试.结果是其中三个不能干预,但我不确定在其他平台是否无法干预.

最后,如果我可以再次提出我的问题.是否标准还证实,不仅FSEEK不能干预seubsequent写,而且功能倒带fsetpos

如果标准确认,请说明表明确认的声明在哪里.

否则,如果标准未确认,请说明表示拒绝的声明在哪里.

关于我的问题,我需要知道的是标准确实确认编译器编写者必须完全执行此操作或确实执行此操作等以确认标准的确定性,仅此而已

Jon*_*ler 2

对于流 I/O,既不会rewind()fsetpos()不会覆盖附加模式 \xe2\x80\x94 fseek()。当写入发生时,会发生隐式的追加模式查找;定位操作是独立的,仅影响隐式查找的起始位置,而不影响写入发生的位置。

\n\n

对于文件描述符 I/O,pwrite()\xe2\x80\x94 定位写入 \xe2\x80\x94 会覆盖追加模式,但其他操作不会。POSIX 规定:pwrite()函数应与 等效write(),只是它写入给定位置并且不更改文件偏移量(无论是否O_APPEND设置)。

\n

  • 在 Linux 上要小心。[Linux 上的 `pwrite()` 已损坏](http://man7.org/linux/man-pages/man2/pread.2.html):“POSIX 要求打开带有 `O_APPEND` 标志的文件应该具有对 `pwrite()` 写入数据的位置没有影响。但是,在 Linux 上,如果使用 `O_APPEND` 打开文件,则 `pwrite()` 会将数据追加到文件末尾,无论 * 的值如何抵消*。” (2认同)