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 :

fopen non correct


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Par défaut fopen non correct
    bonjours à tous.

    je suis actuellement en train de développer un petit serveur de sauvegarde de fichier (texte et binaire) mais je me retrouve avec un problème (je suppose que vous vous en doutez ^^)

    mon problème est :
    j'ai une fonction qui est doit m'ouvrir un fichier en écriture et faire des test dessus pour vérifier qu'il n'y as pas eu d'erreur lors de l'ouverture car le nom de fichier est dynamique.
    les paramètres sont le nom du fichier (char *) et son dossier (char *) cependant lors de la création du fichier celui ci se retrouve avoir un nom tronqué à 4 caractère. de plus si je tente de fermer le fichier je me retrouve avec une erreur de free m'indiquant que le pointeur du fichier est incorect (c'est ce que j'en ais déduis)...
    ci-dessous je vous joint le code de la fonction (le fclose est la juste pour tester l'erreur il n'est pas présent dans la vraie version)

    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
    FILE *RFopen(char *nomFichier,char *dossier){
     
    char *location=strdup(dossier);
    FILE *fichier;
    strcat(location,nomFichier);
        printf("localisation : '%s'\n",location);
        fichier=fopen(location,"wb");
        if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }else{
        printf("Fichier ouvert: %s \nDans %s\n",nomFichier,dossier);}
        fclose(fichier);
        return fichier;
    }
    /** \brief ouverture d'un fichier en mode binaire
     * \param nom du fichier
     * \param dossier de stockage du fichier
     * \return file descriptor
     */
    merci d'avance

  2. #2
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonsoir
    Concrètement tu as des adresses invalides.
    Attention à l'utilisation de la fonction "strdup" elle retourne nulle quand elle n'a pas assez de mémoire pour effectuer le traitement de la chaîne ou de la sous-chaîne. il faut également faire attention à la concaténation comment pourrais-tu savoir si cela a bien fonctionné ? Et pourquoi vouloir créer et tester un fichier sans écrire dedans ?
    Le mieux serait de savoir si des données à traiter existent et dans ce cas on crée le fichier pour pouvoir le manipuler dans le cas contraire, on ne fait rien
    exemple ( exemple pas optimisé à s'en n'inspirer pour faire une adaptation ou une correction ).
    à bientôt
    Code C : 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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    void f_WriteData( const char *p_src, const char *p_dst, const char *p_data ){
     
    	char *ptr = NULL;
    	FILE *pFile = NULL;
     
    	if( (p_src == NULL) || (p_data == NULL) ){
    		fprintf( stderr,"Aucun non de fichier ou donnée disponible\n");
    		exit( EXIT_FAILURE );
    	}
    	else if( (p_src != NULL) && (p_dst == NULL) ){
    		pFile = fopen( p_src, "a+" );
    		if( pFile == NULL ){
    			perror("Erreur ouverture du fichier\n");
    			exit( EXIT_FAILURE );
    		}
    	}
    	else{
    		ptr = (char*)calloc( (sizeof(p_src)+sizeof(p_dst) ) +2, sizeof(char) );
    		if( ptr == NULL ){
    			perror("Erreur allocation de sauvergarde\n");
    			exit( EXIT_FAILURE );
    		}
     
    	#if __STDC_VERSION__ >= 199901L
    			if( ! snprintf( ptr, sizeof(ptr), "%s%s%s", p_dst,"/", p_src ) ){
    				free( ptr );
    				ptr = NULL;
    				perror("Echec de la concaténation\n");
    				exit( EXIT_FAILURE );
    			}
    	#else
    			if( strcat( ptr, p_dst ) != NULL ){
    				if( strcat( ptr, "/" ) != NULL ){
    					if( NULL == strcat( ptr, p_src ) ){
    						free( ptr );
    						ptr = NULL;
    						perror("Impossible de faire une concaténation\n");
    						exit( EXIT_FAILURE );
    					}
    				}else{
    					free( ptr );
    					ptr = NULL;
    					perror("Impossible de faire une concaténation\n");
    					exit( EXIT_FAILURE );
    				}
    			}else{
    				free( ptr );
    				ptr = NULL;
    				perror("Echec de la concaténation\n");
    				exit( EXIT_FAILURE );
    			}
    	#endif
     
    		pFile = fopen( ptr, "a+" );
    		if( pFile == NULL ){
    			free( ptr );
    			ptr = NULL;
    			perror("Erreur ouverture du fichier\n");
    			exit( EXIT_FAILURE );
    		}
    	}
     
    	/* Ecriture des des données */
    	if( fputs( p_data, pFile) == EOF ){
    		free( ptr );
    		perror("Erreure écriture des données\n");
    		ptr = NULL;
    	}
     
    	fclose( pFile );
    	free( ptr );
    	ptr = NULL;
    }
     
    int main( void ){
     
    	f_WriteData("Coucou.txt", "Teste","Bonjours\n" );
    	return( EXIT_SUCCESS );
    }

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Par défaut
    pour ta question sur pourquoi crée le fichier sans rien écrire dedans:

    il se trouve que pour rendre mon code lisible et ré-adaptable (c'est aussi pour ça que je mets des commentaire après chacune de mes fonctions ^^) au besoin j’essaie de rendre mes fonctions avec très peu de code dedans et un code spécifique (j’entends par la une fonction travaillant sur un fichier ne touche pas à un socket et inversement enfin quand c'est possible)

    en fin le but de la fonction est juste de m'ouvrir un fichier en écriture pour que ce fichier sois remplie dans la fonction qui l'as appeler (pour te donner une idée je mets le code de la fonction l'appelant)

    pour info Drecv est une fonction qui reçoit des donnée que le client lui as envoyer (un peu comme recv mais elle fait une vérification avec le client sur les donnée (enfin c'est pas encore bien implémenter mais c'est prévue))

    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
    24
    25
    26
    27
    28
    29
       void frecv(SOCKET csock,char *dossier){
        int ctrl=0;
        char buffer[BUFFERSIZE];
        char nomFichier[BUFFERSIZE];
        Drecv(nomFichier,csock);
        FILE *fichier=RFopen(nomFichier,dossier);
        while(ctrl>0)
       {
        ctrl=Drecv(buffer,csock);
        if(ctrl==3){
        if(!strcmp(buffer,"EOF")){ /* EOF est envoyer en tant que caractère à la fin de l'envoie du fichier il s'agit des 3 caractères E,O,F et non -1 */ 
                printf("\nEnd of file!!!\n");
                break;
        }else{
        fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
        }
        }
        else{
        fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
            }
       }
        fclose(fichier);
    }
    /** \brief reception d'un fichier
     * nom + corp
     * \param socket sur lequel ecouter
     * \param dossier ou stocker le fichier
     * \return void
     */
    pour ton code j'en vais m'en inspirer pour faire mes vérifications si ça te dérange pas

    effectivement je ne check pas encore si la concaténation est bonne (je suis autodidacte en C donc j'ai pas mal de chose que je devrais savoir que je ne sais pas ^^) mais c’était pour ça que je fais un printf (je suis encore encore en phase de dev et je me doute que ce n'est pas une super vérification mais je viens juste de me mettre à gérer ce genre de problème donc je n'ai pas encore vraiment l'habitude avec ce genre de chose)

    P.S merci pour ta réponse rapide

  4. #4
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonsoir
    Citation Envoyé par Comandant Chaos Voir le message
    pour ta question sur pourquoi crée le fichier sans rien écrire dedans:

    il se trouve que pour rendre mon code lisible et ré-adaptable (c'est aussi pour ça que je mets des commentaire après chacune de mes fonctions ^^) au besoin j’essaie de rendre mes fonctions avec très peu de code dedans et un code spécifique (j’entends par la une fonction travaillant sur un fichier ne touche pas à un socket et inversement enfin quand c'est possible)

    en fin le but de la fonction est juste de m'ouvrir un fichier en écriture pour que ce fichier sois remplie dans la fonction qui l'as appeler (pour te donner une idée je mets le code de la fonction l'appelant)
    Je pense concrètement que tu n'as rien compris de ce que j'avais écrit et si c'est le cas, je m'en excuse d'avance. J'essayais de te faire comprendre ici, que l'on travaille sur un ou des fichiers à condition que des données existent et quand peut par la suite les manipuler pour effectuer de divers traitements par exemple, une sauvegarde.
    Et à ce que je sache en ne touche pas a ta fameuse histoire de socket et que veux-tu réadapter de plus à ton programme l'écriture ou la lecture, la façon de les écrire peut-être ou tout simplement une méthode révolutionnaire de traitement de fichier . . ?

    Monseigneur, quand t'en crée un où des fichiers, c'est pour traiter les informations dans le but de les sauvegarder ou lire.

    Un fichier en anglais "file" est une suite d’informations, enregistrées sur un support physique et identifié par un nom. par lequel les manipulations peuvent être la création d'un fichier donc le déclarer pour qu’il existe et l’initialiser ou savoir s'il existe dans ce cas en effectuer de différentes tâches avec, exemple: écriture ou lecture donc lire ou écrire des informations sinon à quoi peut-il servir ?
    modifier certaines données, le détruire dans le cas où il a plus d'utilité.

    Citation Envoyé par Comandant Chaos Voir le message
    pour info Drecv est une fonction qui reçoit des donnée que le client lui as envoyer (un peu comme recv mais elle fait une vérification avec le client sur les donnée (enfin c'est pas encore bien implémenter mais c'est prévue))

    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
       void frecv(SOCKET csock,char *dossier){
     
        Drecv(nomFichier,csock);
        FILE *fichier=RFopen(nomFichier,dossier);
        while(ctrl>0)
       {
        ctrl=Drecv(buffer,csock);
        ........
        fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
        }
        }
        else{
        fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
            }
       }
        fclose(fichier);
    }
    /** \brief reception d'un fichier
     * nom + corp
     * \param socket sur lequel ecouter
     * \param dossier ou stocker le fichier
     * \return void
     */
    P.S merci pour ta réponse rapide
    je lâche l'affaire monseigneur @Comandant Chaos , car je suis K.O et donc je vais me coucher

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Par défaut
    bonjour,

    après relecture de tes deux post je pense avoir compris ce que tu veux me dire :
    Le mieux serait de savoir si des données à traiter existent et dans ce cas on crée le fichier pour pouvoir le manipuler dans le cas contraire, on ne fait rien
    si j'ai bien compris tu me conseillerais au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    appeler ma  fonction qui ouvre mon fichier 
    remplir entièrement mon fichier dans la fonction appelante grâce aux donnée du socket.
    fermer ce fichier dans la fonction appelante
    plus qu'elle que chose comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    vérifier que des donnée existe sur mon socket
    si non on ne fait rien
    si oui j'ouvre mon fichier 
    j’écris mon bloc de donnée en mode apending
    je ferme le fichier
    et je boucle sur ces opérations tant que le contenue du socket est différent de ma marque de fin de fichier
    est ce ça que tu veux me faire comprendre ?

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    char *location=strdup(dossier);
    FILE *fichier;
    strcat(location,nomFichier);
    ...
    strdup() alloue de la mémoire pour stocker un duplicata de la chaine dossier. Il n'y a pas de place pour y ajouter avec le strcat() la chaine nomFichier. Tu obtiens un dépassement du buffer location avec un comportement indéterminé. Le programme doit être dès ce stade considéré comme détruit.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 05/04/2009, 11h31
  2. Valeur BCD non correcte
    Par JP.NUAGE dans le forum Bases de données
    Réponses: 1
    Dernier message: 28/11/2008, 11h26
  3. Affichage info-bulle non correct suivant le navigateur
    Par [ced] dans le forum Mise en page CSS
    Réponses: 9
    Dernier message: 18/06/2008, 09h38
  4. Affichage non correct d'une image
    Par AnonCoder dans le forum Langage
    Réponses: 2
    Dernier message: 03/11/2006, 13h51
  5. Variables javascript non correctement définies
    Par LLaurent dans le forum XMLRAD
    Réponses: 5
    Dernier message: 11/05/2004, 12h39

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