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 :

commande qui copie fichier avec options


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2011
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Décembre 2011
    Messages : 33
    Points : 22
    Points
    22
    Par défaut commande qui copie fichier avec options
    Bonjour,
    Je dois écrire une commande qui permet de copier un fichier. Cette commande pourra avoir 3
    options (éventuellement combinables) :
    ccp -v : vérifie si le fichier destination existe déjà. Si c’est le cas, un message d’erreur est renvoyé.
    ccp -a : copie en mode « append », le contenu du fichier source est recopié à la fin du fichier destination.
    ccp -b off1 -e off2 : seuls sont copiés les octets du fichier source compris entre les positions
    off1 et off2.

    Voici ce que j'ai commencé mais je suis un peu perdu..

    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
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <getopt.h>
     
    #define VOPT 1;
    #define AOPT 2;
    #define OFF1 4;
    #define OFF2 8;
     
    #define _XOPEN_SOURCE
     
    void cpp(int n, char* arg[]) {
    	int off1, off2;
    	int opt = opt(n, arg, off1, off2);
     
    	int c = O_CREAT;
    	if (opt & VOPT == 1) {
    		c = c & O_EXCL;
    	}
    	if (opt & AOPT == 1) {
    		c = c & O_APPEND;
    	}
    	/*if (opt & OFF1 == 1) {
    		c = c & O_EXCL;
    	}
    	if (opt & OFF2 == 1) {
    		c = c & O_EXCL;
    	}*/
    	int dest = open(arg[0], c);
    	if (dest == - 1) {
    		perror("open");
    		exit(EXIT_FAILURE);
    	} else {
    		char buf[256];
    		int src = open(arg[n-1], O_RDONLY);
    		if (src == -1) {
    			perror("open");
    		}
    		int r = read(src, buf, 256);
    		while (r != 0) {
    			if (r == -1) {
    				perror("read");
    				exit(EXIT_FAILURE);
    			}
    			if (write(dest, buf, 256)) == -1) {
    				perror("write");
    				exit(EXIT_FAILURE);
    			}
    			r = read(src, buf, 256);
    		}
    	}
    }
     
    int opt(int n, char* arg[], int *off1, int *off2) {
    	int mask = 0;
     
    	for (int i = 0; i < n; i++) {
    		int opt = getopt(n, arg, "vab:e:");
    		/*if (opt == -1) {
    			perror("getopt");
    			exit(EXIT_FAILURE);
    		}*/
    		switch(opt) {
    			case "v" :
    				mask = mask | VOPT;
    				break;
    			case "a" :
    				mask = mask | AOPT;
    				break;
    			case "b:" :
    				mask = mask | OFF1;
    				off1 = optarg;
    				break;
    			case "e:" :
    				mask = mask | OFF2;
    				off2 = optarg;
    				break;
    		}
    		return mask;
    }
    pourriez vous m'aider ?

    Merci d'avance

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Disons, créez une fonction qui permette de vérifier si un fichier existe
    Cette fonction prendra un nom de fichier en paramètre et retournera un int (0 si le fichier n'existe pas).
    Ça sera un bon, début, non ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Bonjour,

    Déjà, compiler ce que tu as écrit et analyser les warnings et erreurs te permettrait de remettre tout ça un peu plus d'équerre.

    Sans l'option C99 :

    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
    plx@sony:~$ gcc -c essai.c 
    essai.c: In function ‘cpp’:
    essai.c:16:15: erreur: called object ‘opt’ is not a function
    essai.c:18:10: erreur: ‘O_CREAT’ undeclared (first use in this function)
    essai.c:18:10: note: each undeclared identifier is reported only once for each function it appears in
    essai.c:19:12: erreur: expected ‘)’ before ‘;’ token
    essai.c:20:11: erreur: ‘O_EXCL’ undeclared (first use in this function)
    essai.c:22:12: erreur: expected ‘)’ before ‘;’ token
    essai.c:23:11: erreur: ‘O_APPEND’ undeclared (first use in this function)
    essai.c:37:28: erreur: ‘O_RDONLY’ undeclared (first use in this function)
    essai.c:47:31: erreur: expected expression before ‘==’ token
    essai.c:47:36: erreur: expected statement before ‘)’ token
    essai.c: In function ‘opt’:
    essai.c:59:2: erreur: ‘for’ loop initial declarations are only allowed in C99 mode
    essai.c:59:2: note: use option -std=c99 or -std=gnu99 to compile your code
    essai.c:66:4: erreur: l'étiquette du « case » ne se réduit pas en une constante entière
    essai.c:69:4: erreur: l'étiquette du « case » ne se réduit pas en une constante entière
    essai.c:72:4: erreur: l'étiquette du « case » ne se réduit pas en une constante entière
    essai.c:74:10: attention : assignment from incompatible pointer type [enabled by default]
    essai.c:76:4: erreur: l'étiquette du « case » ne se réduit pas en une constante entière
    essai.c:78:10: attention : assignment from incompatible pointer type [enabled by default]
    essai.c:82:1: erreur: expected declaration or statement at end of input
    ou avec :

    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
    plx@sony:~$ gcc -c essai.c -std=c99
    essai.c: In function ‘cpp’:
    essai.c:16:15: erreur: called object ‘opt’ is not a function
    essai.c:18:10: erreur: ‘O_CREAT’ undeclared (first use in this function)
    essai.c:18:10: note: each undeclared identifier is reported only once for each function it appears in
    essai.c:19:12: erreur: expected ‘)’ before ‘;’ token
    essai.c:20:11: erreur: ‘O_EXCL’ undeclared (first use in this function)
    essai.c:22:12: erreur: expected ‘)’ before ‘;’ token
    essai.c:23:11: erreur: ‘O_APPEND’ undeclared (first use in this function)
    essai.c:31:2: attention : implicit declaration of function ‘open’ [-Wimplicit-function-declaration]
    essai.c:37:28: erreur: ‘O_RDONLY’ undeclared (first use in this function)
    essai.c:47:31: erreur: expected expression before ‘==’ token
    essai.c:47:36: erreur: expected statement before ‘)’ token
    essai.c: In function ‘opt’:
    essai.c:66:4: erreur: l'étiquette du « case » ne se réduit pas en une constante entière
    essai.c:69:4: erreur: l'étiquette du « case » ne se réduit pas en une constante entière
    essai.c:72:4: erreur: l'étiquette du « case » ne se réduit pas en une constante entière
    essai.c:74:10: attention : assignment from incompatible pointer type [enabled by default]
    essai.c:76:4: erreur: l'étiquette du « case » ne se réduit pas en une constante entière
    essai.c:78:10: attention : assignment from incompatible pointer type [enabled by default]
    essai.c:82:1: erreur: expected declaration or statement at end of input
    il y a de quoi faire.


    D'autres remarques en vrac.


    • Traiter/décoder les arguments de la ligne de commande dans la fonction chargée d'effectuer la copie n'est pas une bonne chose. Tu traites des choses trop différentes et qui n'ont guère de rapport. De plus, tu fais dépendre "cpp" de "opt" et réduis du même coup le contexte d'utilisation de "cpp". Ajoute les paramètres qu'il faut (pas des paramètres trop marqués argc/argv) dans la fonction qui s'occupe de la copie (nom de fichier, offsets, ...).

    • cpp et opt pour des noms de fonctions ... pas très parlant. Ca ressemble plus à des noms de variables. Tu peux un peu plus te lacher sur les noms de fonctions !

    • ooops sur la même ligne 16: int opt = opt(n, arg, off1, off2);

    • tu ne te sers de la valeur retournée par read que pour gérer les erreurs et fins de fichiers, mais jamais pour spécifier, dans le write, le nombre d'octets à écrire ... les fichiers dont la taille est multiple de 256 ne courent pas les rues et - en dehors des autres problèmes - ta dernière écriture se passera mal quasiment tout le temps (que vaudront les derniers octets du buffer ... traces de la précédente lecture ...)

    • #définit une "constante" du style BUFSIZE au lieu de truffer tes lignes de 256. Le jour où tu voudras changer la valeur, une seule modification sera suffisante et tu n'en oublieras pas

    • Elimine les "exit" à la hussarde dans ta fonction de copie. Fais lui retourner un code retour (plus de void) et n'arrête pas brutalement le programme quand tu es dans cette fonction. Profites-en pour fermer les fichiers ouverts. Un exit se traite (peut se traiter) à un niveau supérieur, pas là.

    • L'indentation et le mélange des déclarations de variables et des instructions n'aident pas

    • Pourquoi (sous Unix/Linux du moins) utiliser des appels systèmes (open, read, write) plutôt que de passer par des FILE, fread, fwrite ? Impression de pouvoir plus finement "tuner" les différents modes d'ouvertue via les O_xxx ? mouais ... les w/wb et a/ab de fopen feraient tout aussi bien l'affaire et je pense que le résultat serait plus lisible et que tu t'y perdrais moins

    • Et un petit main pour pouvoir tester, non ?
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

Discussions similaires

  1. Copie fichiers avec pop up et annulation
    Par anthoof dans le forum VBScript
    Réponses: 0
    Dernier message: 05/06/2014, 12h03
  2. Réponses: 1
    Dernier message: 15/11/2010, 21h13
  3. Copie fichier avec SSH2
    Par Général03 dans le forum Langage
    Réponses: 11
    Dernier message: 17/12/2009, 19h51
  4. Comment vider un fichier avec option r+
    Par shazad dans le forum Débuter
    Réponses: 15
    Dernier message: 10/12/2008, 18h32

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