2012-06-13 5 views
8

Как определить, является ли файл пустым? Файл открывается программой C, работающей на платформе Windows. Я хочу открыть файл в режиме добавления, и, если пустой, сначала напечатайте заголовок для него.Как определить, пуст ли файл?

// 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 его r и использовать fseek/ftell/fclose, а затем fopen его снова a+, но я думаю, что это можно сделать без открытия и закрытия файла несколько раз.

+0

Операции ввода-вывода файлов различаются между операционными системами, поэтому ... с какой ОС вы работаете? –

+1

'Невозможно открыть выходной файл CSV ...' является каноническим примером сообщения об ошибке * *. Укажите фактическое имя файла и причину ошибки ('man perror' и' man strerror'). –

+0

@EitanT: это для Windows –

ответ

6

На самом деле, когда fopen ИНГ файла в режиме добавления, указатель файла сначала в начале файла , Он перемещается до конца, как только вы что-то пишете или используете 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. 
1

Вы можете позвонить _stat() и получить значение st_size в struct _stat (вам не нужно открывать файл).
Заявленные в sys/types.h с последующим sys/stat.h
Я не знаю программирование для Windows, но это может помочь вам: http://msdn.microsoft.com/en-us/library/14h5k7ff.aspx

2

При открытии файла с fopen с режимом a+, все пишущие операции будут выполняться в конце файла. Вы можете переместить внутренний указатель в любом месте файла для чтения, но операции записи вернут его в конец файла. Начальная позиция указателя для чтения находится в начале файла.

Для этого вам необходимо позвонить fseek(pFile, 0, SEEK_END) на ваш указатель FILE.

+0

Да, это так! Я понял это всего десять минут назад. Большое спасибо. –

+0

Не обновлял страницу ... извините :) –

Смежные вопросы