8

ファイルが空かどうかを判断するにはどうすればよいですか? このファイルは、Windows プラットフォームで実行されている C プログラムによって開かれます。ファイルを追加モードで開き、空の場合は最初にヘッダーを出力したいと考えています。

// Open CSV & write header
report_csv = fopen("SNR.csv", "a+");
if (!report_csv) {
    fprintf(stderr, "Unable to open CSV output file...");
    return -1;
}
if (!ftell(report_csv)) {
    fprintf(report_csv, "Column A;Column B;Column C\n");
}
// ... print data to file
fclose(report_csv);

ftellファイルが空でない場合、現在のファイル サイズを返すこと を期待していました。これは、上記のコードがループしているために発生します。

ただし、ftell常に戻り0、ヘッダーが複数回出力されます。

/ /でそれを使用してから、で再度使用できるfopenことはわかっていますが、ファイルを何度も開いたり閉じたりしなくても、これを行うことができると思います。rfseekftellfclosefopena+

4

3 に答える 3

6

実際、fopen追加モードでファイルを ing する場合、ファイル ポインタは最初はファイルの先頭にあります。何かを書いたり使用したりするとすぐに最後に移動しますfseek

fseek(report_csv, 0, SEEK_END);の前に追加する必要がありましたif (!ftell(report_csv))

これを確認しましょう。
コード:

#include <stdio.h>

int main(int argc, char **argv) {
    FILE *test;
    size_t size;
    char buf[100];

    /* Truncate file */
    test = fopen("test", "w");
    if (!test) {
        fprintf(stderr, "Cannot open file `test`!\n");
        return 1;
    }

    /* Write something */
    fprintf(test, "Something. ");
    fclose(test);

    /* Open in append */
    test = fopen("test", "a+");
    if (!test) {
        fprintf(stderr, "Cannot open `test` in append mode!\n");
        return 1;
    }

    /* Try to get the file size */
    size = ftell(test);
    printf("File pointer is: %d\n", size);
    fseek(test, 0, SEEK_END);
    size = ftell(test);
    printf("After `fseek(test, 0, SEEK_END)`, the file pointer is: %d\n", size);

    /* Append */
    fprintf(test, "And that. ");
    fclose(test);

    /* Same without fseek */
    test = fopen("test", "a+");
    if (!test) {
        fprintf(stderr, "Cannot open `test` in append mode!\n");
        return 1;
    }
    fprintf(test, "Hello! ");
    size = ftell(test);
    printf("File size is now: %d\n", size);
    fclose(test);

    /* Try to read */
    test = fopen("test", "r");
    if (!test) {
        fprintf(stderr, "Unable to open `test` for reading!\n");
        return 1;
    }
    printf("File contents:\n\t");
    while (test && !feof(test)) {
        fgets(buf, sizeof(buf), test);
        printf("%s", buf);
    }

    /* Cleanup & exit */
    fclose(test);
    printf("\n\nExiting.\n");

    return 0;
}

出力:

File pointer is: 0
After `fseek(test, 0, SEEK_END)`, the file pointer is: 11
File size is now: 28
File contents:
        Something. And that. Hello!

Exiting.
于 2012-06-13T13:41:11.387 に答える
2

モードでファイルを開くとfopena+すべての書き込み操作はファイルの最後で実行されます。内部ポインターは、読み取り用にファイル内の任意の場所に再配置できますが、書き込み操作ではファイルの末尾に戻されます。読み取りの初期ポインター位置は、ファイルの先頭です。

fseek(pFile, 0, SEEK_END)したがって、FILEポインターでを呼び出す必要があります。

于 2012-06-13T13:50:42.947 に答える
1

呼び出し_stat()て値st_sizeを取得できますstruct _stat(ファイルを開く必要はありません)。
Declared in にsys/types.h続いてsys/stat.h
I don't know Windows programming, but it can help you: http://msdn.microsoft.com/en-us/library/14h5k7ff.aspx

于 2012-06-13T13:34:39.790 に答える