2012-06-13 16 views
8

Comment déterminer si un fichier est vide? Le fichier est ouvert par un programme C exécuté sur la plate-forme Windows. Je veux ouvrir un fichier en mode ajout, et, s'il est vide, d'abord imprimer un en-tête.Comment puis-je déterminer si un fichier est vide?

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

Je me attendais ftell pour retourner la taille du fichier en cours si le fichier n'a pas été vide, ce qui se produit parce que le code ci-dessus est mis en boucle. Toutefois, ftell renvoie toujours 0 et l'en-tête est imprimé plusieurs fois.

Je sais que je pourrais fopen avec r et utiliser fseek/ftell/fclose puis fopen à nouveau avec a+, mais je pense qu'il est possible de le faire sans ouvrir et fermer le fichier plusieurs fois.

+0

Les opérations d'E/S sur fichiers varient d'un système d'exploitation à l'autre, alors ... quel est le système d'exploitation avec lequel vous travaillez? –

+1

'Impossible d'ouvrir le fichier de sortie CSV ...' est l'exemple canonique d'un message d'erreur * bad *. Incluez le nom du fichier réel et la raison de l'erreur ('man perror' et' man strerror'). –

+0

@EitanT: c'est pour Windows –

Répondre

6

En fait, quand fopen ing un fichier en mode append, le pointeur de fichier est d'abord au début du fichier . Il se déplace à la fin de celui-ci dès que vous écrivez quelque chose ou utilisez fseek. J'ai juste besoin d'ajouter fseek(report_csv, 0, SEEK_END); avant mon if (!ftell(report_csv)).

Vérifions cela.
code:

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

Sortie:

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

Vous pouvez appeler _stat() et obtenir la valeur st_size en struct _stat (vous n'avez pas besoin d'ouvrir le fichier).
Déclaré en sys/types.h suivie sys/stat.h
je ne savez pas comment la programmation Windows, mais il peut vous aider: http://msdn.microsoft.com/en-us/library/14h5k7ff.aspx

2

Lors de l'ouverture d'un fichier avec fopen avec le mode a+, sera effectué toutes les opérations d'écriture à la fin du fichier. Vous pouvez repositionner le pointeur interne n'importe où dans le fichier pour le lire, mais les opérations d'écriture le ramèneront à la fin du fichier. La position initiale du pointeur pour la lecture est au début du fichier. Vous devez donc appeler un fseek(pFile, 0, SEEK_END) sur votre pointeur FILE

+0

Oui, c'est vrai! Je pensais que c'était juste il y a dix minutes. Merci beaucoup. –

+0

N'a pas actualisé la page ... désolé :) –

Questions connexes