Création d'un dossier personnalisé
Résolu
maniqk
-
maniqk -
maniqk -
Bonjour,
Je cherche à créer des dossiers à partir d'un nom entré par un utilisateur.
J'ai vu dans une autre discussion que je pouvais faire :
#include <direct.h>
mkdir("monDossier");
pour créer un dossier nommé "monDossier".
Est il possible de mettre comme nom de dossier celui entré par l'utilisateur via un scanf par exemple ? Je voudrais quelque chose dans ce genre là :
#include <stdio.h>
#include <direct.h>
int main()
{
char nomDossier[20];
printf("Choisissez le nom du dossier :");
scanf("%s",nomDossier);
mkdir(nomDossier);
}
Pouvez vous m'aider ?
Merci d'avance
P.S : Désolé pour la "présentation", je ne sais même pas comment on saute une ligne...
Je cherche à créer des dossiers à partir d'un nom entré par un utilisateur.
J'ai vu dans une autre discussion que je pouvais faire :
#include <direct.h>
mkdir("monDossier");
pour créer un dossier nommé "monDossier".
Est il possible de mettre comme nom de dossier celui entré par l'utilisateur via un scanf par exemple ? Je voudrais quelque chose dans ce genre là :
#include <stdio.h>
#include <direct.h>
int main()
{
char nomDossier[20];
printf("Choisissez le nom du dossier :");
scanf("%s",nomDossier);
mkdir(nomDossier);
}
Pouvez vous m'aider ?
Merci d'avance
P.S : Désolé pour la "présentation", je ne sais même pas comment on saute une ligne...
2 réponses
-
Salut maniqk,
Il n'y a pas de moyen en C standard ISO de créer un répertoire, les moyens de faire cela en C dépendent du système et/ou du compilateur utilisé.
Quel est ton système d'exploitation et quel est le compilateur que tu utilises ?
Dal-
-
Bonsoir maniqk,
Alors, la réponse n'est pas simple, comme souvent avec Microsoft.
1.
La fonctionmkdir()
est "déconseillée" par Microsoft, qui l'a rendue obsolète et conseille d'utiliser_mkdir()
à la place.
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mkdir?redirectedfrom=MSDN&view=msvc-160&viewFallbackFrom=vs-2019
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mkdir-wmkdir?redirectedfrom=MSDN&view=msvc-160&viewFallbackFrom=vs-2019
Selon cette dernière page, le prototype est :
int _mkdir(const char *dirname);
Dans la pratique, MinGW référence les deux fonctions dans <direct.h>
https://searchcode.com/codesearch/view/18141172/
en incluant <direct.h>, tu devrais donc pouvoir faire fonctionner ton code, qui va en réalité appeler le_mkdir()
de la Microsoft runtime library. Donc, si tu utilises cette façon de faire, je pense que c'est mieux d'appeler la fonction dans ton code_mkdir()
, pour bien signifier dans ton code que c'est le "mkdir à la Microsoft" qui est appelé.
Il faudrait, aussi, dans ton code, au minimum récupérer la valeur de retour de la fonction, pour vérifier que la création s'est bien passée (cf. la page de MSDN précitée qui indique que si la fonction retourne -1 cela signifie qu'une erreur s'est produite), et inclure <errno.h> ou <stdlib.h> pour tester la valeur de errno si tu veux en savoir plus sur la cause de l'erreur et informer l'utilisateur.
Tu devrais aussi contrôler que le nom récupéré est un nom de répertoire valide selon Windows et décider si tu permets la création d'un répertoire n'importe où (ta saisie acceptant des noms du type "c:\temp\truc\machin" ou sous un répertoire existant donné en n'acceptant que des saisies du type "bidule" sans antislashs ou slashs ou autres bidules non autorisés dans les noms de répertoires Windows).
https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#file_and_directory_names
2.
Maintenant, il faut savoir que sous Windows, le choix demkdir()
ou_mkdir()
n'est pas forcément le plus adapté.
mkdir()
est en fait une fonction POSIX (norme utilisée sur les systèmes de type Unix), qui est normalisée sur ces systèmes et dispose d'un prototype différent permettant de régler les permissions du répertoire à créer, définie dans <sys/stat.h> avec ce prototype :
int mkdir(const char *path, mode_t mode);
cf. https://pubs.opengroup.org/onlinepubs/009695399/functions/mkdir.html
Comme tu l'observeras, il y a un 2ème paramètre pour préciser les permissions.
La fonction_mkdir()
de la Microsoft runtime library (oumkdir()
obsolète) n'en prend qu'un (le nom du répertoire à créer) et ne gère pas les permissions. Microsoft donne donc "une sorte" demkdir()
qui ressemble à la fonction POSIX, mais qui ne fonctionne qu'à moitié... ce qui m'amène au point suivant.
3.
La façon "à la Windows" de créer un répertoire est d'utiliser l'API de Windows, qui permet la création de répertoire avec un contrôle sur les permissions.
Il faudrait utiliserCreateDirectory()
(inclure <windows.h>), en particulier si tu dois gérer les permissions (avec GetLastError pour la gestion d'erreurs).
BOOL WINAPI CreateDirectory( _In_ LPCTSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes );
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createdirectorya?redirectedfrom=MSDN
Le 2ème argument est un pointeur sur une structure SECURITY_ATTRIBUTES définie là : https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85)?redirectedfrom=MSDN
Tu as des exemples de code fixant des permissions au moyen de cette structure sur SO, là : https://stackoverflow.com/questions/690780/how-to-create-directory-with-all-rights-granted-to-everyone
Si tu n'as pas à de soucier des permissions,_mkdir()
est bien sûr plus simple.
CreateDirectory peut aussi être utilisé avec un 2ème argument mis à NULL (la doc dit "If lpSecurityAttributes is NULL, the directory gets a default security descriptor. The ACLs in the default security descriptor for a directory are inherited from its parent directory.").
ouf.. je crois que j'ai fini :-D
Dal -
-
-
Bonjour
En plus de ce qui a été dit par @Dal votre code source est incomplet et ne marchera pas, car il manque comme argument les droits du répertoire. Le prototype exact de la fonction estint mkdir(const char *, mode_t);
Ce qui donnerait peu prêt le code sources suivantes.#define SIZE_NAME_DIR 15 /* Taille buffer */ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/dir.h> #include <sys/stat.h> int main( void ){ char buffer[SIZE_NAME_DIR]; /* buffer de saisie */ fprintf( stdout, "Non du repertoire ou sous repertoire\n" ); fprintf( stdout, ">>" ); /* Boucle de saisie non du repertoire CTRL-D /CTRL-Z pour arrêter la saisie ou atteindre SIZE_NAME_DIR -1 */ while( (NULL) != fgets( buffer, (SIZE_NAME_DIR-1), stdin ) ) fprintf( stdout, ">>\t %s\n", buffer ); buffer[ strlen(buffer)-1 ] = '\0'; /* Creation du repertoire avec les droit utilisateur & message erreur en cas d'echec. */ if( mkdir( buffer, S_IRWXU ) ){ fprintf( stderr, "(%d)\tErreur creation du repertoire %s\n\t:%s\n", errno, buffer, strerror(errno) ); return EXIT_FAILURE; } return EXIT_SUCCESS; }-
Salut sambia39
while( (NULL) != fgets( buffer, (SIZE_NAME_DIR-1), stdin ) )
SIZE_NAME_DIR tout simplement. Pas besoin du -1 :-).
buffer[ strlen(buffer)-1 ] = '\0';
J'imagine que c'est pour enlever le '\n'. Sauf que le '\n' n'est pas ajouté s'il n'y a pas la place. Dans ce cas, on utilise plutôt strchr() pour rechercher l'éventuel '\n' et on le positionne à 0.
Cdlt, -
Salut sambia39, fiddy :-)
int mkdir(const char *, mode_t);
est le prototype de la fonction POSIX, pas de la fonctionmkdir()
ou plus exactement_mkdir()
disponible sur Windows, notre ami maniqk utilisant Windows7.
cf. ma réponse détaillée.
Dal -
-
-