Création d'un dossier personnalisé

Résolu/Fermé
maniqk - 15 sept. 2015 à 14:49
 maniqk - 17 sept. 2015 à 10:26
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...

A voir également:

2 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
16 sept. 2015 à 12:34
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
0
Bonjour Dal,

Je suis sous Windows 7 et je travaille avec Code Blocks.
Du coup, la fonction mkdir ne fonctionne pas ?
En fait je ne peux pas tester pour le moment j'attends qu'on m'installe le logiciel... (c'est mon pc pro)
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 16/09/2015 à 19:40
Bonsoir maniqk,

Alors, la réponse n'est pas simple, comme souvent avec Microsoft.

1.


La fonction
mkdir()
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 de
mkdir()
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 (ou
mkdir()
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" de
mkdir()
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 utiliser
CreateDirectory()
(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
0
Bonjour Dal,

Merci pour cette réponse très complète ! Je vais de ce pas tester tout ça...

maniqk
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
16 sept. 2015 à 15:04
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 est
int 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;
}
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
16 sept. 2015 à 15:31
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,
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
16 sept. 2015 à 19:34
Salut sambia39, fiddy :-)

int mkdir(const char *, mode_t);
est le prototype de la fonction POSIX, pas de la fonction
mkdir()
ou plus exactement
_mkdir()
disponible sur Windows, notre ami maniqk utilisant Windows7.

cf. ma réponse détaillée.

Dal
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
16 sept. 2015 à 22:10
Salut fiddy , Dal ;)
@Dal, Ok autant pour moi pour la fonction
@fiddy merci pour la correction à mon habitude je me précipite un peu trop.
à bientôt
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
Modifié par fiddy le 16/09/2015 à 23:54
D'accord avec [Dal].
Sur Windows, on utilise _mkdir() ou l'api Win avec CreateDirectory().
C'est kif kif.
Cdlt,
0