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 d'une chaine concaténée


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 53
    Points : 22
    Points
    22
    Par défaut fopen d'une chaine concaténée
    Bonjour,

    Mon problème est le suivant, j'ai un fichier qui contient le résultat d'un ls et un char * qui contient un chemin d'accès au dossier.

    Je dois ouvrir chaque fichier contenu dans le résultat de ls. Pour ce faire, je dois concaténer le chemin d'accès(/home/user...) + le nom du fichier (foo.txt).

    Je le fais de cette façon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    const char *path = "/home/user/logs";
     
    void envoiFichier(char *nomFichier) {
    	char *fichier;
    	int longueur = 256;
    	fichier = malloc(longueur);
    	memset(fichier, '\0', sizeof(fichier));
           snprintf(fichier, longueur, "%s/%s\0", path, nomFichier);
    Puis j'imprime le résultat, ça me donne quelque chose de correct (/home/user/foo.txt ) . Mais lorsque je veux passer le résultat de la concaténation à fopen, j'obtiens un No Such file or directory alors que le fichier existe bel et bien.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ((file = fopen(fichier, "r")) == NULL) perror("Erreur dans l'open du fichier.info");
    Je crois que c'est un problème de '\0' ou quelque chose comme ça, mais j'ai aucune idée de comment le résoudre !
    Pouvez-vous m'aider ?

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Salut

    Pour ton problème, je ne saurai pas t'aider. Par contre, si tu affiches la chaine et que ça correspond au résultat attendu, le problème vient forcément d'ailleurs. Problème de permission ?

    Par contre, il y a moyen d'alléger ton code. Pourquoi utiliser malloc et memset, qui sont inutiles ici ?

    Voilà plus simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void envoiFichier(char const * const nomFichier)
    {
    	char fichier[256];
     
    	snprintf(fichier, 256, "%s/%s", path, nomFichier);
     
    /*	(...) */
     
    }
    Si tu tiens absolument à utiliser le pointeur path comme objet global, le mieux est de le rendre constant, afin d'éviter les mauvaises surprises :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char * const path = "/home/user/logs";

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 53
    Points : 22
    Points
    22
    Par défaut
    Merci, je vais essayer de retirer les malloc etc...

    Je dispose des bonnes permissions, et si j'écris directement le chemin d'accès dans le fopen(), je n'ai pas d'erreur ! C'est pour ça que je ne comprend pas, il affiche le bon résultat

    /home/user/logs/foo.txt (= fichier)

    mais dans le fopen() :

    fopen(fichier) != fopen("/home/user/logs/foo.txt")

    D'où ça pourrait venir ?

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    si j'écris directement le chemin d'accès dans le fopen(), je n'ai pas d'erreur !
    C'est pas normal.

    Montre ta fonction, au complet.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 53
    Points : 22
    Points
    22
    Par défaut
    C'est une application client-serveur qui liste le contenu d'un dossier, et envoie le tout au serveur.

    La partie qui pose problème se trouve dans le client.


    Voila la fonction avec le fopen() qui pose problème
    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
    void envoiFichier(int socket, char *nomFichier) {
    	FILE* file;
    	char *fichier;
    	int longueur = 256;
            char buffer[4096],*message;
    	fichier = malloc(longueur);
    	memset(fichier, '\0', sizeof(fichier));
           snprintf(fichier, longueur, "%s/%s\0", path, nomFichier);
           printf(fichier);
    	if ((file = fopen(fichier, "r")) == NULL) perror("Erreur dans l'open du fichier.info"); //fonctionne avec youpi
    	else {
    		message = malloc(4096);
    		memset(message, '\0', sizeof(message));
    		while (fgets(buffer,4096,file) !=  NULL) {
    			strcat(message,buffer);	
    		}
    		envoyer(socket, message);
    		fclose(file);
    	}
    }
    La fonction qui appelle envoiFichier
    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
    void traitement(int socket) {
    	FILE* file;
            char *buffer;
    	if ((file = fopen("output.txt", "r")) == NULL) perror("Erreur dans l'open de output.txt");
     
     
    	buffer = malloc(4096);
    	memset(buffer,'\0',sizeof(buffer));
     
    	while (fgets(buffer,4096,file) !=  NULL) {
    		envoyer(socket, buffer);
    		envoiFichier(socket,buffer);
    	}
    	fclose(file);
    }

  6. #6
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 950
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 950
    Points : 5 667
    Points
    5 667
    Par défaut
    Sia,

    Je ne vois pas trop où est ton problème, mais tes memset ne font pas ce que tu penses : sizeof(fichier) renvoie la taille de la variable fichier, donc la taille d'un pointeur, et pas la taille réservée pour ce pointeur !!

  7. #7
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par pazze Voir le message
    Puis j'imprime le résultat, ça me donne quelque chose de correct (/home/user/foo.txt ) .
    Plutôt qu'un simple printf(fichier), utilises une impression du style printf("<%s>\n", fichier) et donne le résultat exact (c'est à dire y compris les retours à ligne) obtenu, voire affiche le code hexa de chaque caractère jusqu'au \0 terminal.

  8. #8
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 129
    Points
    28 129
    Par défaut
    Bonjour,

    Tu testes le code de retour de fopen, mais pas celui de malloc. Pourquoi ?
    Tu ne liberes pas la memoire allouee.
    Le fait de travailler en allocation dynamique ne sert a rien : tu n'as rien de dynamique dans ton code, tu travailles sur une chaine de 256 char.
    Et enfin, snprintf te garantit que ta chaine se termine par un \0. Il n'est donc pas utile de l'ecrire toi meme.

  9. #9
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Tu as très probablement un '\n' à la fin de ton nom de fichier. Il faut l'enlever (ie. mettre à '\0' à la place) avant de passer la chaine à open, puisque le nom de fichier sur ton disque ne contient, lui, pas de newline.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 53
    Points : 22
    Points
    22
    Par défaut
    le résultat de printf("<%s>\n", fichier) donne


    </home/user/logs/Server.info
    >


    EDIT : j'ai réglé le problème avec un strtok() Merci

  11. #11
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Mais non malheureux

    Il suffit de regarder la chaine à l'indice retourné par snprintf(), et si c'est un '\n', y écrire un '\0'.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 53
    Points : 22
    Points
    22
    Par défaut
    J'ai essayé, mais j'obtiens des segfault sans trop comprendre pourquoi et j'ai du mal à comprendre comment ça marche.

    Par exemple, index = snprintf....

    à [index], j'ai bien \0
    à [index+1], j'ai \n
    et à [index-1], j'ai ni l'un ni l'autre

    Dans ce cas la, comme le \0 est avant le \n, ça ne pose pas de problème je pense....

  13. #13
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    C'est à index - 1 en fait. A condition que tu vires ce "\0" qui ne sert à rien dans ton snprintf().

Discussions similaires

  1. Concaténation d'une chaine avec un champ
    Par arjo54 dans le forum Access
    Réponses: 0
    Dernier message: 27/07/2007, 13h34
  2. Concaténer une chaine et un nombre pour former un nom de variable ?
    Par debie1108 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 30/04/2007, 07h38
  3. Comment concaténer une chaine de caractères avec un espace ?
    Par blanchonvincent dans le forum MATLAB
    Réponses: 6
    Dernier message: 07/04/2007, 21h53
  4. pb concaténation d'une chaine avec un caractère
    Par P'tite Nélodie dans le forum C
    Réponses: 9
    Dernier message: 06/11/2006, 19h09
  5. concaténer un type char à une chaine
    Par Fabs dans le forum C
    Réponses: 8
    Dernier message: 11/11/2005, 15h21

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