IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

fichier illisible après copie


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2012
    Messages : 7
    Par défaut fichier illisible après copie
    Bonjour,
    mon petit programme sert à copier un fichier passé en paramètre.

    j'ai testé avec une image bmp.
    le fichier crée ne peut pas être lu par la visionneuse Window, pourtant, si je le compare a son original dans un éditeur de texte, son contenu est identique.

    comment cela s'explique ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
     
    int main( int argc, char *argv[] ){
        if( argc == 2 ){
        FILE *f = fopen(  argv[1] , "r" );
            if( f ){
                char *s = malloc( strlen( argv[1] ) + 4 );
                strcpy( s , "cop_" );
                strcat( s , argv[1] );
                FILE *d = fopen( s , "w+" );
                int cf = fgetc( f ) , cd = EOF ;
                while( cf != EOF ){
                     cd = fputc( cf , d );
                     cf = fgetc( f );
                }
                free( s );
                printf( cd == EOF ? "erreur de copie\n" : "ok\n" );
            } else printf( "fichier manquant\n" );
        } else printf( "args: fsource\n" );
        return 0 ;
    }

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Tu ne vérifies pas que ton fichier de destination a bien été ouvert, de plus, tu ne ferme pas les fichiers que tu as ouvert avec fclose.

    Et tu ne gère pas non-plus les erreurs pouvant survenir lors de la lecture cf man.

    Sinon, pourquoi ne pas utiliser :
    - fseek pour aller en fin de fichier ;
    - ftell pour connaitre la taille de ton fichier ;
    - rewind pour revenir en début de fichier ;
    - fread pour lire en une seule fois ton fichier ;
    - fwrite pour écrire en une seule fois ton fichier ;

    N.B : tu peux aussi te passer de fseek, fteell et rewind en utilisant un buffer (généralement un tableau de 4096 char).

    Rq :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *s = malloc( strlen( argv[1] ) + 4 +  1);
    Ne pas oublier le '\0' final.

    Rq2 : pour t'éviter d'entrer des valeurs en dur tu peux aussi faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const char * prefixe = "cop_";
    char *s = malloc(strlen(cop_) + strlen( argv[1] ) + 1 );
    strcpy( s , prefixe );

  3. #3
    Membre éclairé Avatar de Ngork
    Homme Profil pro
    Barbare IT
    Inscrit en
    Avril 2009
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Barbare IT
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 160
    Par défaut
    Les conseils de Neckara sont tout-à-fait judicieux.
    Toutefois, si tu ne peux pas ouvrir ensuite ton image BMP copiée, c'est parce que tu as créé cette copie comme un fichier texte alors qu'une image BMP est un fichier binaire.
    Sous Windows, tu rajoutes un petit b derrière ton w+ et tout ira bien !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FILE *d = fopen( s , "w+b" );

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Ngork Voir le message
    Les conseils de Neckara sont tout-à-fait judicieux.
    Toutefois, si tu ne peux pas ouvrir ensuite ton image BMP copiée, c'est parce que tu as créé cette copie comme un fichier texte alors qu'une image BMP est un fichier binaire.
    Sous Windows, tu rajoutes un petit b derrière ton w+ et tout ira bien !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FILE *d = fopen( s , "w+b" );
    C'est en effet possible mais cela me paraîtrait bizarre.
    Pour moi la différence entre le mode binaire et le mode texte est que les entiers seront écrits sur le nombre d'octet sur lesquels ils sont codés ( 0xFF => 1 octets ) pour le mode binaire et qu'en mode texte, ils sont écrit en "toute lettre" ("255" => 3 octets ).
    Ainsi pour une lecture/écriture octet par octet le mode texte et le mode binaire ne devraient pas vraiment avoir de différences mais je peux me tromper.
    Il faudrait que je fasse quelques petits tests sous Windows un de ces jours

    N.B. A noter que sous Linix, l'option "b" est désormais ignoré

  5. #5
    Membre éclairé Avatar de Ngork
    Homme Profil pro
    Barbare IT
    Inscrit en
    Avril 2009
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Barbare IT
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 160
    Par défaut
    Citation Envoyé par Neckara Voir le message
    C'est en effet possible mais cela me paraîtrait bizarre.
    Pour moi la différence entre le mode binaire et le mode texte est que les entiers seront écrits sur le nombre d'octet sur lesquels ils sont codés ( 0xFF => 1 octets ) pour le mode binaire et qu'en mode texte, ils sont écrit en "toute lettre" ("255" => 3 octets ).
    Ainsi pour une lecture/écriture octet par octet le mode texte et le mode binaire ne devraient pas vraiment avoir de différences mais je peux me tromper.
    Il faudrait que je fasse quelques petits tests sous Windows un de ces jours

    N.B. A noter que sous Linix, l'option "b" est désormais ignoré
    Oui, sous Linux, cela ne fait pas de différence, c'est pourquoi j'ai précisé sous Windows ... , système pour lequel les spécifications de la fonction fopen() s'appliquent strictement avec la nécessité de distinguer les fichiers textes des fichiers binaires :

    Text files contain printable characters and control characters organized into lines. Each line ends with a new-line character, except for the last line, which does not require one. The system may insert or convert control characters in an output text stream.

    Note: Data output to a text stream may not compare as equal to the same data on input.

    Binary files contain a series of characters. For binary files, the system does not translate control characters on input or output.
    Ce qui signifie en gros :

    Les fichiers textes contiennent des caractères affichables et des caractères de contrôle organisés en lignes. Chaque fin de ligne s'achève par un caractère de nouvelle ligne, sauf pour la dernière ligne qui n'en a pas besoin. Le système peut insérer ou convertir des caractères de contrôle dans le flux du fichier en sortie.

    Note: Les données en sortie vers un fichier texte pourraient ne pas être équivalentes aux données en entrée.

    Les fichiers binaires contiennent une série de caractères. Pour les fichiers binaires, le système ne traduit pas les caractères de contrôle en entrée comme en sortie.
    Et le fait que Bernabé01 ait mentionné s'être assuré de la validité de la copie par une comparaison dans un éditeur de texte (alors qu'un bitmap n'est pas un fichier texte ) confirme l'analyse de l'erreur, non ?

    Par ailleurs, je viens de compiler son code sous Windows (Code::Blocks + MinGW) et cela marche parfaitement si on ajoute le petit b que je préconise ... + un autre petit b derrière le r pour l'ouverture du fichier BMP source :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FILE *f = fopen(  argv[1] , "rb" );
    ...
    FILE *d = fopen( s , "w+b" );

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Pour moi la différence entre le mode binaire et le mode texte est que les entiers seront écrits sur le nombre d'octet sur lesquels ils sont codés ( 0xFF => 1 octets ) pour le mode binaire et qu'en mode texte, ils sont écrit en "toute lettre" ("255" => 3 octets ).
    Ainsi pour une lecture/écriture octet par octet le mode texte et le mode binaire ne devraient pas vraiment avoir de différences mais je peux me tromper.
    Salut
    C'est pas exactement ça.
    A la base, il n'y a aucune différence entre un fichier texte et un fichier binaire. Ainsi donc si le fichier "toto.txt" commence par "255" et que le fichier "titi.mp3" commence par "0x32 0x35 0x35" ce sont donc (pour ce début du moins) exactement la même chose.
    La différence vient quand on traite ces fichiers. Si le premier est ouvert par un éditeur, il convertira les octets en ascii et te les affichera à l'écran. Et si le second est ouvert par un lecteur audio, il convertira ces mêmes octets en son musical.

    S'il fallait s'arrêter là, ce serait merveilleux. On se ferait plus ch. avec texte/binaire car tout serait "la même chose". Le problème arrive avec un petit détail dans les fichiers textes windows qui diffère des fichiers textes Unix: le saut de ligne. Sous Unix, le caractère saut de ligne est normalisé via un "\n" tout simple (un caractère pour un effet). Donc quand l'éditeur trouve ce caractère, il passe à la ligne et t'affiche donc de belles lignes bien propres. Mais sous Windows, ce saut est représenté par un "\r" (retour du charriot en début de ligne) suivi de "\n" (décalage sur la ligne suivante). Exactement comme le faisaient les machines à écrire. A l'époque c'était peut-être pratique (un retour charriot sans décaler la ligne permettait de souligner du texte ou de l'effacer) mais en informatique cela ne rime à rien ; ce qui n'a pas empêché les concepteurs dos/zindow de l'implanter dans leurs format.

    Et c'est cette différence qui oblige maintenant à
    • spécifier ascii/binary lors des transferts ftp hétérogènes (en mode ascii le transfert effectue la conversion "\n" vers "\r\n" et inversement)
    • ouvrir sous zindow les fichiers en mode "w" pour texte et "wb" pour binaire (en mode texte, un caractère "\n" est converti en "\r\n" alors qu'il n'est rien converti en mode binaire)

    Comme quoi, alors qu'on aurait pu avoir une gestion de fichiers simple, par la volonté de quelques incapables qui n'ont jamais voulu admettre leur crétinerie on continue aujourd'hui à se prendre la tête pour rien...

    Maintenant, pour en revenir à ce que t'as dit, écrire "2" "5" "5" sera bien entendu plus long que d'écrire 0xff mais ce n'est pas le type de fichier qui fera que tu auras "2" "5" "5" ou 0xff mais ta façon de l'écrire...

    Citation Envoyé par Neckara Voir le message
    N.B. A noter que sous Linix, l'option "b" est désormais ignoré
    Linix ? Un nouvel OS ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Sve@r
    zindow
    Ça doit être le pendant de Linix ^^

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Maintenant, pour en revenir à ce que t'as dit, écrire "2" "5" "5" sera bien entendu plus long que d'écrire 0xff mais ce n'est pas le type de fichier qui fera que tu auras "2" "5" "5" ou 0xff mais ta façon de l'écrire...
    Il me semblait que faire un fprintf(myFile, "%d") n'avait pas le même effet selon si on avait ouvert ce fichier en mode texte ou en mode binaire ( en tout cas ça ne serait pas très incohérent).
    Bon je ne peux plus trop vérifier vu que "b" est ignoré maintenant


    Citation Envoyé par Sve@r Voir le message
    Linix ? Un nouvel OS ???
    Voyons, il faut sortir de sa caverne un petit peu plus souvent...
    Qui ne connaît pas Linix aujourd'hui?
    Linix est un OS libre et gratuit contrairement à ses concurrents Zindow et Mapple.
    Bien sûr il existe d'autres OS comme Solakis, LSD, ...

Discussions similaires

  1. RegExp aprés copie fichier excell
    Par Mordok dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 27/03/2012, 10h53
  2. Réponses: 2
    Dernier message: 01/02/2012, 10h43
  3. Copie de fichier d'après un historique annexe
    Par Benoitt dans le forum Administration système
    Réponses: 16
    Dernier message: 28/11/2011, 22h47
  4. Fichier corrompu après copie
    Par Patricia_ dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 11/08/2009, 11h16
  5. Fichier excel corrompu apres copie
    Par jaudurier dans le forum Maven
    Réponses: 6
    Dernier message: 03/07/2007, 10h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo