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 :

Chemin d'un fichier


Sujet :

C

  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 19
    Par défaut Chemin d'un fichier
    Bonjour,
    je suis débutante en C et j'ai un exo qui me demande de retourner le chemin absolu à partir d'un chemin relatif donné en argument.
    J'ai fait un code et j'ai un problème dans ma concaténation.
    merci de m'aider
    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
    30
    31
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    /*
     *retourne le chemin absolu a partir d'un chemin relatif
     *chemin absolu : il affiche le chemin depuis la racine
     *chemin relatif : il affiche le chemin depuis l'endroit ou on est
     * la commande pwd retourne le chemin absolu d'un fichier
     */
     
     
    #define MAX_PATH 512
     
    char * relatifToAbsolu(char *fichier){
    	char* buf;
    	buf = malloc(MAX_PATH * sizeof(char));
    	buf = getcwd(buf, MAX_PATH);
    	if (buf == NULL) {
    		fprintf(stderr, "\nErreur: echec de l'appel a getcwd.\n\n");
    	}
    	return strcat(buf,fichier);
     
    }
     
    int main(int argc, char *argv[]){
      char * path = relatifToAbsolu("chemin relatif du fichier");
      printf("%s \n",path);
      return 0;
    }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 487
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /*
     * la commande pwd retourne le chemin absolu d'un fichier
     */
    Non. La commande « pwd » te renvoie le répertoire de travail, c'est-à-dire celui dans lequel ton processus a été lancé, et qui va servir de point de départ aux chemins relatifs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	buf = getcwd(buf, MAX_PATH);
    Ce n'est pas mal, mais ce n'est pas une bonne idée d'écraser buf avec la valeur de retour de getcwd, parce que si quelque chose ne tourne pas rond, cette fonction ne va pas libérer elle-même l'espace que tu as alloué. « buf » doit donc toujours contenir la valeur renvoyée par malloc() quoi qu'il se passe, pour que tu puisses le libérer à la fin. Il faut également que tu vérifies que malloc() renvoie une valeur valide avant de continuer, car cette allocation peut échouer elle-aussi…

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	return strcat(buf,fichier)
    Essaie d'utiliser strncat() plutôt que strcat() pour éviter les débordements de tampon.

    Pense également à libérer dans ton main l'espace retourné par ta fonction avec free().

  3. #3
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 788
    Par défaut
    Hello,

    Pour getcwd(), pas besoin de faire de malloc, ce code fonctionne sans 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
    21
    22
    23
    24
    25
    26
    27
    #include <dir.h>
    #include <stdio.h>
    #include <stdlib.h>
     
    char *relatifToAbsolu(char *filename) {
    	char *buf;
     
    	buf=getcwd(NULL,MAXPATH+1); // Je pense que MAX_PATH ne compte pas le '\0
    	if(buf) {
    		buf=realloc(buf,strlen(buf)+strlen(filename)+2);
    		strcat(buf,"\\");
    		strcat(buf,filename);
    		}
    	return(buf);
    }
     
    int main(void) {
    	char *buf;
     
    	buf=relatifToAbsolu("un ficher");
    	if(buf) {
    		printf("%s\n",buf);
    		free(buf);
    		}
    	else puts("Erreur: buf est null");
    	return(0);
    }
    Edgar.

    Edit: et il n'y a pas de débordement à craindre, car je pense que MAX_PATH n'inclut pas MAX_FILE et MAX_EXT. Or on concatène un nom de ficher (et éventuellement une extension) à un path....

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Je m'étais amusé à faire ce genre de code une fois. Toutefois le mien prenait en compte "." et ".." pour raccourcir le chemin affiché.
    Exemple: on lui passe "/toto/./../titi" et il répond "/titi"

    En fait, j'utilise une liste chainée pour chaque nom. Et quand le nom est ".." je supprime simplement le dernier élément de la liste

    Pour amusement et à titre d'info, voici le code
    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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    // Donne le chemin absolu d'un chemin donné en argument
    // Prend en compte le répertoire courant pour les noms relatifs
    // Supprime les noms inutiles (comme ".")
    // Supprime le dernier nom ajouté quand il tombe sur ".."
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
     
    #define MAXPATHLEN			(512)		// Devrait être défini dans <unistd.h> mais, bizarrement, je ne l'y trouve pas...
     
    typedef struct s_noeud {
    	char nom[MAXPATHLEN + 1];
    	struct s_noeud *next;
    } t_noeud;
     
    typedef struct {
    	t_noeud *path;
    } t_chemin;
     
    // Création noeud
    t_noeud* create_node(const char const *nom)
    {
    	t_noeud *noeud;
    	if ((noeud=malloc(sizeof(t_noeud))) == NULL)
    		return NULL;
    	strncpy(noeud->nom, nom, MAXPATHLEN);
    	noeud->nom[MAXPATHLEN]='\0';		// strncpy() ne rajoute pas le '\0' quand n est atteint
    	noeud->next=NULL;
    	return noeud;
    }
     
    // Initialisation chemin
    void init_chemin(t_chemin* const chemin)
    {
    	chemin->path=NULL;
    }
     
    // Ajout nom au chemin
    t_noeud* append_chemin(t_chemin* const chemin, const char const *nom)
    {
    	t_noeud *noeud;
    	t_noeud *current;
     
    	// Création nouveau noeud sur le nom demandé
    	if ((noeud=create_node(nom)) == NULL)
    		return NULL;
     
    	// Si on est sur le premier nom
    	if (chemin->path == NULL)
    	{
    		// Ce nom devient le premier de notre chemin
    		chemin->path=noeud;
    		return noeud;
    	}
     
    	// Recherche dernier noeud du chemin
    	for (current=chemin->path; current->next != NULL; current=current->next);
     
    	// Ajout du noeud courant
    	current->next=noeud;
     
    	// On renvoie le noeud ajouté (permet de détecter l'erreur de malloc)
    	return noeud;
    }
     
    // Suppression dernier noeud
    void pop_chemin(t_chemin* const chemin)
    {
    	t_noeud *current;
     
    	// S'il n'y a plus de noeud c'est qu'on est à la racine "/"
    	if (chemin->path == NULL)
    		return;
     
    	// S'il n'y a qu'un noeud
    	if (chemin->path->next == NULL)
    	{
    		// On le supprime
    		free(chemin->path);
    		chemin->path=NULL;
    		return;
    	}
     
    	// Recherche avant-dernier noeud
    	for (current=chemin->path; current->next->next != NULL; current=current->next);
     
    	// Suppression dernier noeud
    	free(current->next);
     
    	// Modification avant-dernier noeud
    	current->next=NULL;
    }
     
    // Suppression chemmin
    void free_chemin(t_chemin* const chemin)
    {
    	t_noeud *current;
    	t_noeud *previous;
     
    	// S'il n'y a plus de noeud
    	if (chemin->path == NULL)
    		return;
     
    	// Traitement de tous les noeuds
    	current=chemin->path;
    	do {
    		previous=current;
    		current=current->next;
    		free(previous);
    	} while (current != NULL);
     
    	// Le chemin a été vidé - On le réinitialise
    	init_chemin(chemin);
    }
     
    // Afficher chemin
    void print_chemin(const t_chemin const *chemin)
    {
    	t_noeud *current;
     
    	fputc('/', stdout);
    	for (current=chemin->path; current != NULL; current=current->next)
    		printf("%s/", current->nom);
    	fputc('\n', stdout);
    }
     
    // Chemin
    void cibler(char* const nom)
    {
    	t_chemin chemin;
    	char *strtok_mem;
    	char *split;
    	char cwd[MAXPATHLEN + 1];
     
    	// Initialisation chemin
    	init_chemin(&chemin);
     
    	// Si le nom ne commence pas par '/'
    	if (nom[0] != '/')
    	{
    		// Récupération du chemin courant
    		getcwd(cwd, MAXPATHLEN);
     
    		// Découpage du chemin courant
    		split=NULL;
    		while ((split=strtok_r(split == NULL ?cwd :NULL, "/", &strtok_mem)) != NULL)
    		{
    			// Ajout du nom au chemin
    			if (append_chemin(&chemin, split) == NULL)
    				fprintf(stderr, "Erreur alloc(%s) - Abandon !!!", split);
    		}
    	}
     
    	// Découpage du nom
    	split=NULL;
    	while ((split=strtok_r(split == NULL ?nom :NULL, "/", &strtok_mem)) != NULL)
    	{
    		// Si le nom est "."
    		if (strcmp(split, ".") == 0)
    			// On le passe
    			continue;
     
    		// Si le nom est ".."
    		if (strcmp(split, "..") == 0)
    		{
    			// On supprime le dernier noeud et on passe
    			pop_chemin(&chemin);
    			continue;
    		}
     
    		// Ajout du nom au chemin
    		if (append_chemin(&chemin, split) == NULL)
    			fprintf(stderr, "Erreur alloc(%s) - Abandon !!!", split);
    	}
     
    	// Affichage chemin
    	print_chemin(&chemin);
     
    	// Libération chemin
    	free_chemin(&chemin);
    }
     
    int main(int argc, char *argv[])
    {
    	char **pt_arg;
    	for (pt_arg=argv+1; *pt_arg; pt_arg++)
    		cibler(*pt_arg);
    }

    Bien entendu c'est uniquement à titre d'info que je donne ce code. Tu peux l'utiliser et regarder le résultat mais surtout ne le donne pas comme étant le tien, ton prof verra immédiatement que ce n'est pas possible...

    [edit]Cet aprem j'ai eu un peu de temps alors je me suis amusé à le refaire. Mais cette fois, je passe par une simple chaine que j'agrandis ou que je réduis selon le nom à y positionner
    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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    // Donne le chemin absolu d'un chemin donné en argument
    // Prend en compte le répertoire courant pour les noms relatifs
    // Supprime les noms inutiles (comme ".")
    // Supprime le dernier nom ajouté quand il tombe sur ".."
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
     
    #define SZ_ALLOC			(512)
    #define MAXPATHLEN			(512)		// Devrait être défini dans unistd.h mais, bizarrement, je ne l'y trouve pas...
     
    typedef struct {
    	char *nom;
    	size_t sz_alloc;
    	size_t len;
    } t_chemin;
     
    // Initialisation chemin
    void init_chemin(t_chemin* const chemin)
    {
    	chemin->nom=NULL;
    	chemin->sz_alloc=0;
    	chemin->len=0;
    }
     
    // Ajout nom au chemin
    char* append_chemin(t_chemin* const chemin, const char const *nom)
    {
    	// Si la taille du nom total dépasse la taille allouée (ne pas oublier le '/')
    	if ((chemin->len + strlen(nom) + sizeof(char)) > chemin->sz_alloc)
    	{
    		// Agrandissement nom - On prend un peu de marge pour éviter trop de realloc
    		char *new;
    		chemin->sz_alloc=chemin->len + strlen(nom) + sizeof(char) + SZ_ALLOC;
    		if ((new=realloc(chemin->nom, (chemin->sz_alloc + 1 /* le '\0' */) * sizeof(char))) == NULL)
    			return NULL;
    		chemin->nom=new;
    	}
     
    	// Concaténation nom
    	(chemin->len != 0 ?strcat :strcpy)(chemin->nom, "/");
    	strcat(chemin->nom, nom);
     
    	// Mise à jour longueur nom
    	chemin->len=strlen(chemin->nom);
     
    	// On renvoie le nom créé (permet de détecter l'erreur de malloc)
    	return chemin->nom;
    }
     
    // Suppression dernier nom
    void pop_chemin(t_chemin* const chemin)
    {
    	char *pt;
     
    	// Recherche dernier "/"
    	if ((pt=strrchr(chemin->nom, '/')) != NULL)
    	{
    		// Suppression fin chemin
    		*pt='\0';
     
    		// Mise à jour longueur nom
    		chemin->len=strlen(chemin->nom);
    	}
    }
     
    // Chemin
    void cibler(char* const nom)
    {
    	t_chemin chemin;
    	char *strtok_mem;
    	char *split;
    	char cwd[MAXPATHLEN + 1];
     
    	// Initialisation chemin
    	init_chemin(&chemin);
     
    	// Si le nom ne commence pas par '/'
    	if (nom[0] != '/')
    	{
    		// Récupération du chemin courant
    		getcwd(cwd, MAXPATHLEN);
     
    		// Découpage du chemin courant
    		split=NULL;
    		while ((split=strtok_r(split == NULL ?cwd :NULL, "/", &strtok_mem)) != NULL)
    		{
    			// Ajout du nom au chemin
    			if (append_chemin(&chemin, split) == NULL)
    				fprintf(stderr, "Erreur alloc(%s) - Abandon !!!", split);
    		}
    	}
     
    	// Découpage du nom
    	split=NULL;
    	while ((split=strtok_r(split == NULL ?nom :NULL, "/", &strtok_mem)) != NULL)
    	{
    		// Si le nom est "."
    		if (strcmp(split, ".") == 0)
    			// On le passe
    			continue;
     
    		// Si le nom est ".."
    		if (strcmp(split, "..") == 0)
    		{
    			// On supprime le dernier noeud et on passe
    			pop_chemin(&chemin);
    			continue;
    		}
     
    		// Ajout du nom au chemin
    		if (append_chemin(&chemin, split) == NULL)
    			fprintf(stderr, "Erreur alloc(%s) - Abandon !!!", split);
    	}
     
    	// Affichage chemin
    	printf("%s\n", chemin.nom);
     
    	// Libération chemin
    	free(chemin.nom);
    	init_chemin(&chemin);
    }
     
    int main(int argc, char *argv[])
    {
    	char **pt_arg;
    	for (pt_arg=argv+1; *pt_arg; pt_arg++)
    		cibler(*pt_arg);
    }
    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]

Discussions similaires

  1. [Configuration] chemin d'un fichier dans un include/require
    Par BizuR dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 22
    Dernier message: 31/01/2006, 01h25
  2. Tester le formalisme du chemin vers un fichier ?
    Par elitost dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 07/10/2005, 15h06
  3. [C#] Chemin pour mon fichier CSS
    Par the_new dans le forum ASP.NET
    Réponses: 5
    Dernier message: 23/03/2005, 15h25
  4. [Plugin] Récuperation du chemin d'un fichier!
    Par GRM dans le forum Eclipse Platform
    Réponses: 1
    Dernier message: 21/03/2005, 09h39
  5. Fonction permettant d'afficher le chemin d'un fichier
    Par kilinette dans le forum Langage
    Réponses: 4
    Dernier message: 22/06/2004, 10h52

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