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 :

lire un fichier en mode binaire et le recopier


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut lire un fichier en mode binaire et le recopier
    Bonjour,

    Je suis un débutant en C et je suis bloqué sur un programme. Je dois réaliser un projet qui consiste à créer une commande pour archiver des fichiers. Pour cela, je dois pouvoir stocker dans un seul fichier les contenus et information de plusieurs fichiers. Cependant je n'arrive pas à récupérer le contenu d'un fichier à archiver.
    Donc j'ai ma structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    struct fichier_info{
            size_t path_length; //ok
    	off_t file_length;
            mode_t mode; //ok
            time_t m_time; //ok
            time_t a_time; //ok
            char *nom_file;  //ok
    	char checksum[32]; // osef 
            char path[100]; //ok
    	char* file;
    };
    Dans la consigne qu'on me donne, je dois avoir un type char[] pour le champ file, mais je ne sais pas comment je peux définir la taille de file en avance ! Vu que c'est dans une structure, je ne vois pas comment je pourrais allouer un tableau dynamique... Donc j'ai essayé avec char* pour récupérer des chaines de caractère dans file.
    Je n'ai pas de problème pour la plupart des champs, checksum représente l'empreinte md5 du fichier. Je ne sais pas ce que c'est parce que je ne me suis pas encore renseigné, mais je laisse ca de coter pour l'instant. Ce qui me dérange pour l'instant, c'est de pouvoir recopier le contenu d'un fichier dans le champ file. Je ne veux pas écrire directement le contenu dans un fichier, je voudrais qu'il soit dans la structure car c'est demandé dans la consigne et que pour extraire ca serait plus pratique.

    Avant de vous montrer ma fonction archivage, je vous montre le fichier .txt que je tente d'archiver :
    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
     
    ca gaz ou quoi ??.
     
     
    f
    ezfùe
    cef
    vsd
    v
    ea
    gz
    rds
     
    sdv
    ds
    lol
    Puis ma fonction archivage :
    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
     
    void archivage(int c, char *arg[], int fn, int dd, int d)
    {
      // Pas besoin de s'occuper de fn, dd, d et c. arg[3] contient le fichier à archiver, et arg[2] le nom du fichier d'archive.
      struct fichier_info tab_info;
      printf("Fonction archivage\n");
    	int len,archive,i;
    	FILE* dc; char buf[1024];
    	dd = c-3;
    	char *r = "rb";
    	// J'ouvre le fichier archive (ou je le créé)
    if((archive=open(arg[2],O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO))<0)
                       exit(1);
           //Cette boucle permet de prendre plusieurs arguments mais on s'en fout
    	for(i=3;i<c;i++)
    	  {
    	    //  Ouverture du fichier à archiver avec fopen (ouverture en binaire car r = "rb"
    	        struct stat st;
    		if((stat(arg[i],&st) != 0)|((dc = fopen(arg[i],r))<0))
    		{
    			printf("impossible d archiver %s ",arg[i]);
    			continue;
    		}
    		// On complète la structure tab_info à partir d'ici
    		tab_info.nom_file=arg[i]; char s[] ="okok";
    		printf("nom fichier : /! %s  /!  \n", tab_info.nom_file);
    		strcpy(tab_info.path,chemin(arg[i]));
    		printf("chemin : %s\n", tab_info.path);
    		tab_info.path_length=strlen(tab_info.path)+1;
                    strcat(tab_info.path,"\0");
    		tab_info.mode=st.st_mode;
    		tab_info.a_time=st.st_atime;
    		tab_info.m_time= st.st_mtime;
    		// C'est ici que je tente d'insérer le contenu du fichier dans tab_info.file
    		while(fread(buf,1024,1,dc)> 0) 
    		  {
    		    printf(">>>>>  CC  <<<<<\n");
    		    tab_info.file = strcat(tab_info.file, buf);
    		  }
           	        tab_info.file_length=st.st_size;
     
    		printf("file : \n%s\nBuf : %d\n",tab_info.file);
     
    	       	write(archive,&tab_info,sizeof(struct fichier_info));
    		fclose(dc);
    	}
    	close(archive);
    }

    Et la il se passe un truc de fou, dans le while avec lequel j'appelle fread, CC ne s'affiche pas, donc on ne rentre pas dans la boucle (c'est sur, j'ai bien vérifié). MAIS le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("file : \n%s\nBuf : \n",tab_info.file);
    affiche ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    file : 
    s
     
    sdv
    ds
    lol
    Quand je mets toute la boucle while en commentaire, tab_info.file affiche des caractères bizarres (5-6 caractères hiéroglyphe). Donc du coup je ne pige que dalle, strcat remplirait tab_info.file de la fin du fichier alors qu'on entre même pas dans la boucle (quand elle n'est pas en commentaire)? Mais pourquoi ? Je suis sur qu'il y a une explication logique à cela, mais pour moi ca me semble complètement illogique ! fread ne touche pas à tab_info.file, rien ne devrait changer. Même en mettant fread tout seul, sans le strcat, la même chose s'affiche ! ... ?

    Bref vous l'aurez compris, ca me pique le crâne fortement cette histoire donc j'ai besoin de votre aide svp ! Merci d'avance



    EDIT : J'ai utilisé deux différents open parce que je ne vois pas comment ouvrir en mode binaire avec open, et je n'ai pas vu de fonction tel que fopen, fread et fwrite en cours. Et je viens de modifier le dernier paragraphe qui donnait une fausse information.

    EDIT 2 : Je n'ai pas le droit d'utiliser LA fonction system !

  2. #2
    Membre chevronné
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    855
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 855
    Points : 2 177
    Points
    2 177
    Par défaut
    EDIT 2 : Je n'ai pas le droit d'utiliser des fonctions système !
    open/read/write/close étant des fonctions systèmes, t'es mal barré.

    J'ai utilisé deux différents open parce que je ne vois pas comment ouvrir en mode binaire avec open, et je n'ai pas vu de fonction tel que fopen, fread et fwrite en cours. Et je viens de modifier le dernier paragraphe qui donnait une fausse information.
    En C, on peut dire que les fichiers sont toujours ouverts en mode binaire, il n'y a aucun traitement sur les données lues/écrites exceptés ceux que tu mettras en place. Concernant fopen, fread, fwrite et fclose (ne pas l'oublier !), il te suffit de lire leur manuel respectif dont je t'ai fourni les liens). Je recommande d'ailleurs leur usage plutôt que celui d'open/read/etc...

    Maintenant pour lire le contenu de ton fichier, plusieurs questions se posent :

    1. Est-ce que tu effectues un traitement sur les données lues / écrites ?
    2. As-tu réellement besoin d'avoir l'intégralité de ton fichier dans un seul buffer ?

    Si la réponse à la question 1. est non, tu n'as absolument pas besoin de tout stocker dans un seul buffer, il te suffit de faire un buffer tampon. Explications : en gros tu lis 10 caractères (ce nombre importe peu) et tu les recopies aussitôt dans le nouveau fichier. Tu continues jusqu'à avoir atteint la fin du fichier lu. Félicitations, tu as copié un fichier !

    Si la réponse à la question 1. est oui, je pense que la réponse sera la même pour la question 2. Dans ce cas, il t'est possible de récupérer la taille d'un fichier comme indiqué ici. Ensuite, il te suffit de faire un malloc de la taille retournée et de lire le fichier d'un seul coup. Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    off_t size = get_size();
     
    char *buffer = malloc(sizeof(*buffer) * size);
    fread(buffer, sizeof(*buffer), size, fd);
    fwrite(buffer, sizeof(*buffer), size, new_fd);
    Voilà, j'espère que ça t'aidera.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Désolé, c'est la fonction system, pas les fonctions système.

    Ce que je veux faire, c'est pouvoir mettre le contenu du fichier dans ma structure puisque après je vais devoir extraire les fichiers de l'archive. Si j'écris directement, je ne sais pas comment je pourrais récupérer le contenu d'un fichier, ca risque d'être le bazar ! Donc non je ne modifie pas les données lues ou écrites, mais j'ai besoin "d'ordonner" le contenu du fichier. Ainsi, pour le récupérer il suffira que je read dans un fichier des structures fichier_info.

    Mais je vais tenter d'utiliser ton code et de copier le buffer dans mon tab_info.file, merci !

    EDIT : Enfin je n'aurais même pas besoin de copier le buffer, j'utilise directement tab_info.file comme buffer

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Merci ca fonctionne parfaitement !

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    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 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zulhuky Voir le message
    Bonjour,
    Bonjour,

    Citation Envoyé par Zulhuky Voir le message
    Je suis un débutant en C
    et t'as pas remarqué qu'il y avait une rubrique spécial débutant ???


    Citation Envoyé par Zulhuky Voir le message
    Dans la consigne qu'on me donne, je dois avoir un type char[] pour le champ file, mais je ne sais pas comment je peux définir la taille de file en avance !
    Tu peux pas. Soit tu admets que ton champ ne pourra pas dépasser une certaine taille max et tu crées un champ ayant cette taille, soit tu alloues après avoir récupéré la taille nécessaire.

    Citation Envoyé par Zulhuky Voir le message
    Vu que c'est dans une structure, je ne vois pas comment je pourrais allouer un tableau dynamique...
    Je ne vois pas ce que ça change. Tu peux accéder et allouer un champ de structure au même type qu'une variable simple...
    Exemple d'allocation
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    char *tab1;
    struct {
        int *tab2;
    } ma_var;
     
    tab1=malloc(10 * sizeof(char));
    ma_var.tab2=malloc(20 * sizeof(int));
    free(tab1);
    free(ma_var.tab2);

    Citation Envoyé par Zulhuky Voir le message
    Ce qui me dérange pour l'instant, c'est de pouvoir recopier le contenu d'un fichier dans le champ file. Je ne veux pas écrire directement le contenu dans un fichier, je voudrais qu'il soit dans la structure car c'est demandé dans la consigne et que pour extraire ca serait plus pratique.
    T'es sûr ??? Si t'as un fichier iso de 40G (taille d'un des dernier call of duty par exemple) tu vas te le recopier dans ta structure ??? Tu vas exploser ta RAM...

    Citation Envoyé par Zulhuky Voir le message
    EDIT : J'ai utilisé deux différents open parce que je ne vois pas comment ouvrir en mode binaire avec open, et je n'ai pas vu de fonction tel que fopen, fread et fwrite en cours.
    Si t'es sous Unix/Linux (qui considère tout fichier comme étant binaire) t'as rien à faire. Sous Windows (qui fait chier tous les programmeurs du monde avec sa différence texte/binaire que rien ne justifie) tu rajoutes le flag O_BINARY dans tes flags d'ouverture.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Bon mon archive a toujours la même taille (192 octets), même si je ne mets rien dans tab_info... J'ai l'impression que c'est impossible d'écrire une structure dans un fichier non ? La taille devrait varier en fonction de ce qu'il y a dans tab_info.file ? J'ai tenté d'archiver un fichier de 3Go, ca a mis du temps (p-e 3 minutes) mais mon fichier archive fait toujours 192 octets...
    Donc j'en conclus que c'est impossible de contenir le fichier dans tab_info.file, mais dans ce cas là, comment je peux m'y retrouver si je concatène plein de contenu de fichier et avec leurs informations ? La structure me permet de facilement extraire, mais sans structure je ne vois pas comment faire ?

    EDIT : oui je suis sous linux

  7. #7
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Ne serait-ce pas l'obligation d'écrire une structure détaillant le fichier suivie dudit fichier, et tout ça répété autant de fois que de fichiers ?
    Car stocker les données du fichier dans la structure, ça n'a aucun sens.
    La commande tar procède ainsi : informations du fichier puis données du fichier, et ça recommence jusqu'à stocker toutes les données des fichiers dans un seul fichier.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Ca n'est pas dit explicitement que l'on doit faire une structure pour les informations du fichier, mais ca me semblait évident. En tout cas je suis sur que je ne peux pas contenir le contenu du fichier dans une variable. Je vais faire ce que tu m'as dit dinobogan, cad une structure pour les infos, puis le contenu hors de la structure. Mais ca sera bien plus galère pour l'extraction

    EDIT : Du coup je vais devoir faire un buffer avec une taille limité et dans une boucle while pour recopier le contenu d'un fichier, cad faire un read et write jusqu'à ce que read retourne 0

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    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 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zulhuky Voir le message
    J'ai l'impression que c'est impossible d'écrire une structure dans un fichier non ? La taille devrait varier en fonction de ce qu'il y a dans tab_info.file ?
    Non. Une structure est une suite de variables liées de façon logique (comme par exemple nom+prénom+adresse pour une personne). La taille d'une structure est fixe et est alors la somme des tailles des variables qui la composent. Même si un des champs est un pointeur alloué, la taille reste figée (taille du pointeur, la zone allouée étant ailleurs dans la mémoire).

    Quand au stockage c'est ce qu'on nomme "sérialisation". Il y a plusieurs techiques
    • tu bazardes la structure en vrac dans ton fichier (write(&structure, sizeof structure, fp). De l'autre coté tu récupères bien évidemment tous les octets composant la structure que tu reclaques dans une structure analogue. Ca fonctionnera si tu restes dans la même architecture (car certains compilos rajoutent des octets bidons dans les structures pour les faire "coller" avec l'architecture de l'OS et donc entre deux OS différents ça peut changer). Mais ça ne fonctionnera pas si la structure contient une zone allouée (laquelle se trouve placée dans un autre emplacement mémoire). Dans ce cas, de l'autre coté tu récupères une adresse ne correspondant à rien de concret
    • tu descends les éléments un par un dans un formalisme de ton cru (comme le CSV d'excel). De l'autre coté tu refais l'opération inverse. C'est compatible multi-os et y compris pour les zones allouées puisque tu les traites aussi

    Les autres techniques seront des variations de ces deux techniques de base...

    Citation Envoyé par Zulhuky Voir le message
    Ca n'est pas dit explicitement que l'on doit faire une structure pour les informations du fichier, mais ca me semblait évident.
    Exact - Tu devrais d'ailleurs aller voir le "struct stat"...

    Citation Envoyé par Zulhuky Voir le message
    Mais ca sera bien plus galère pour l'extraction
    Pas forcément. Tu connais la taille du fichier (enfin j'espère) donc tu boucles jusqu'à avoir lu "n=taille" octets...

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Au final j'ai bazardé la structure en enlevant le champ tab_info.file, puis j'ai mis le contenu du fichier juste après et ca s'archive correctement avec la bonne taille !
    Mais j'ai un autre petit problème vraiment con... Je vous mets ma nouvelle fonction archivage :
    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
     
    void archivage(char *arg, char *filename,int i, int ajout)
    {
      struct fichier_info tab_info;
      printf("Fonction archivage\n");
      int archive;
      int dc; char* buf;
    	// J'ouvre le fichier archive (ou je le créé)
      if(ajout == 1)
        {
    if((archive=open(arg[2],O_WRONLY|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO))<0)
                       exit(1);
        }
      else
        {
    if((archive=open(arg[2],O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO))<0)
                       exit(1);
        }
    	        struct stat st;
    		if((stat(filename,&st) != 0)|((dc = open(filename,O_RDONLY))<0))
    		{
    			printf("impossible d archiver %s ",filename);
    			exit(1);
    		}
    		// On complète la structure tab_info à partir d'ici
    		tab_info.nom_file=filename; 
    		printf("nom fichier : /! %s  /!  \n", tab_info.nom_file);
     
    	strcpy(tab_info.path,chemin(filename));
    		printf("chemin : %s\n", tab_info.path);
    		tab_info.path_length=strlen(tab_info.path)+1;
                    strcat(tab_info.path,"\0");
    		tab_info.mode=st.st_mode;
    		tab_info.a_time=st.st_atime;
    		tab_info.m_time= st.st_mtime;
           	        tab_info.file_length=st.st_size;
    		write(archive, &tab_info, sizeof(tab_info));
    		// Insertion du contenu du fichier :
     
    		int n = 0;
    		int s = 0;
    		if((st.st_size )<1024)
    		      {
    			buf = malloc(sizeof(*buf) * tab_info.file_length);
    			s = tab_info.file_length;
    		      } 
    		    else
    		      {
    			buf = malloc(sizeof(*buf) * 1024); 
    			s = 1024;
    		      }
    		write(archive, buf, sizeof(*buf)*s);
    		while(read(dc, buf, sizeof(*buf)*s)!=0)
    		  {
    		    n += 1024;
    		    if((st.st_size - n)<1024 && (st.st_size - n ) > 0)
    		      {
    			buf = malloc(sizeof(*buf) * (tab_info.file_length - n));
    			s = tab_info.file_length - n;
    			write(archive, buf, sizeof(*buf)*s);
    			break;
    		      } 
    		    else if ((st.st_size - n) >= 1024)
    		      {
    			buf = malloc(sizeof(*buf) * 1024); 
    			s = 1024;
    		      }
     
    		  write(archive, buf, sizeof(*buf)*s);
    		  }	       	
    		// Fin insertion du contenu
    		close(dc);
     
    	close(archive);
    }
    J'ai remplacé des arguments dans la fonction, et retiré certaines variables dont je n'ai plus l'utilité. le champ filename est le nom du fichier à archiver. Maintenant je veux appelé ma fonction depuis mon main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int main(int argc, char *argv[]) 
    {
     archivage(argv,argv[3],3,1)
    }
    Mon prototype de ma fonction étant void archivage(char *arg, char *filename,int i, int ajout) , j'ai un problème sur le 2ème argument. Je sais que je pourrais appeler arg[2] comme je l'ai fait avant mais j'ai besoin de la présence de cet argument pour la suite, et j'ai besoin de la faire fonctionner aussi bien avec argv[3] qu'avec une chaine de caractère banale.
    Mon programme ne compile pas. J'ai essayé plein d'autre type, mais j'ai toujours une erreur différente. Voilà ce que me dit le terminal :

    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
     
    arch.c: In function ‘archivage’:
    arch.c:99:1: warning: passing argument 1 of ‘open’ makes pointer from integer without a cast [enabled by default]
     if((archive=open(arg[2],O_WRONLY|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO))<0)
     ^
    In file included from arch.c:3:0:
    /usr/include/fcntl.h:146:12: note: expected ‘const char *’ but argument is of type ‘charextern int open (const char *__file, int __oflag, ...) __nonnull ((1));
                ^
    arch.c:104:1: warning: passing argument 1 of ‘open’ makes pointer from integer without a cast [enabled by default]
     if((archive=open(arg[2],O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO))<0)
     ^
    In file included from arch.c:3:0:
    /usr/include/fcntl.h:146:12: note: expected ‘const char *’ but argument is of type ‘charextern int open (const char *__file, int __oflag, ...) __nonnull ((1));
                ^
    arch.c: In function ‘main’:
    arch.c:235:7: warning: passing argument 1 of ‘archivage’ from incompatible pointer type [enabled by default]
           archivage(argv,argv[3],3,1);
           ^
    arch.c:90:6: note: expected ‘char *’ but argument is of type ‘char **’
     void archivage(char *arg, char *filename,int i, int ajout)
    J'ai donc un problème avec la fonction open. On me demande un const char*, mais si je change l'argument filename en const char*, j'ai encore une erreur. Pourtant, je réussi à utiliser open avec arg[2] qui est de type char* ! Donc je suis confus, ca me parait être une erreur toute bête, j'ai fait des recherches sur internet mais je ne trouve pas la réponse à mon problème qui me pique sévèrement le crâne ! Encore une fois, merci pour votre aide !

  11. #11
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open(arg[2],O_WRONLY|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO))
    Il n'y a rien qui te choque, là, par hasard ?

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par archMqx. Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open(arg[2],O_WRONLY|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO))
    Il n'y a rien qui te choque, là, par hasard ?

    Justement, cette partie de ma fonction fonctionnait très bien avant que je rajoute l'argument filename ! Je n'ai pas du tout modifié cette partie, ni le premier argument. Mais le C est vraiment bizarre, ca te rajoute des erreurs sur des choses que tu n'as jamais modifié Mais au final j'ai remplacé le prototype de la fonction archivage par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void archivage(char *arg[], char filename[],int i, int ajout)
    et ca fonctionne très bien, seulement c'est étrange que char *arg ne fonctionne plus.

  13. #13
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Zulhuky Voir le message
    Justement, cette partie de ma fonction fonctionnait très bien avant que je rajoute l'argument filename ! Je n'ai pas du tout modifié cette partie, ni le premier argument. Mais le C est vraiment bizarre, ca te rajoute des erreurs sur des choses que tu n'as jamais modifié
    C'est bien connu voyons : Un langage de programmation n'a été conçu que dans le seul et unique but de troller les étudiants essayant de l'apprendre !

    Ou alors, on se dit qu'il y a quelque chose que l'on n'a pas fait correctement, et que ce n'est pas le langage qui est en cause, mais soi-même.

    Le C est très "con" : il ne fait que ce qu'on lui demande. Si ça ne marche pas, c'est pas lui !

    Citation Envoyé par Zulhuky Voir le message
    Mais au final j'ai remplacé le prototype de la fonction archivage par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void archivage(char *arg[], char filename[],int i, int ajout)
    et ca fonctionne très bien, seulement c'est étrange que char *arg ne fonctionne plus.
    C'est même très bizarre effectivement. On passe d'un pointeur à un tableau de pointeur... Et bizarrement, d'un coup, arg[2] ne devient plus un char mais un char*, ce qui (encore très bizarrement) deviens le type de paramètre demandé par la fonction open().

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    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 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zulhuky Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main(int argc, char *argv[]) 
    {
     archivage(argv,argv[3],3,1)
    }
    et ca fonctionne très bien, seulement c'est étrange que char *arg ne fonctionne plus.
    Ben peut-être parce que argv n'est pas un char*...

    Citation Envoyé par Zulhuky Voir le message
    Au final j'ai bazardé la structure en enlevant le champ tab_info.file
    A ce propos t'étais pas obligé d'y mettre un pointeur. Un nom de fichier possède une contrainte de taille connue (MAXPATHLEN définie dans unistd.h). Tu peux donc tout à fait définir un char file[MAXPATHLEN + 1 /* pour le '\0' */]; et tu ne t'embêtes plus ni avec le malloc ni avec la sérialisation...

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Justement, cette partie de ma fonction fonctionnait très bien avant que je rajoute l'argument filename ! Je n'ai pas du tout modifié cette partie, ni le premier argument. Mais le C est vraiment bizarre, ca te rajoute des erreurs sur des choses que tu n'as jamais modifié
    Bon apparemment je l'ai modifié sans faire gaffe d'ou le fait que je n'y comprennais que dalle, grosse bourde

    A ce propos t'étais pas obligé d'y mettre un pointeur. Un nom de fichier possède une contrainte de taille connue (MAXPATHLEN définie dans unistd.h). Tu peux donc tout à fait définir un char file[MAXPATHLEN + 1 /* pour le '\0' */]; et tu ne t'embêtes plus ni avec le malloc ni avec la sérialisation...
    Ah oui merci pour l'astuce, mais bon au final ce champ ne me servait à rien vu que je ne pouvais pas archiver de gros fichier

  16. #16
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    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 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zulhuky Voir le message
    Ah oui merci pour l'astuce, mais bon au final ce champ ne me servait à rien vu que je ne pouvais pas archiver de gros fichier
    Euh non, dans mon esprit ce champ était dédié au stockage du nom du fichier et non à son contenu. Je parle d'ailleurs bien de "nom" et "MAXPATHLEN" traduit bien une notion de "longueur de chemin (d'accès au fichier)"...

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Ah ok, en fait c'est mon champ path qui contient le chemin, mais j'ai défini la taille à la barbare en mettant 100. Donc je vais changer ca merci

  18. #18
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2015
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    J'ai un problème avec ma fonction désarchivage pour l'extraction de la structure, mon read ne fonctionne pas :

    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
     
    void desarchivage(char arch[]){
     
       struct fichier_info et;
       struct stat st;
       int archive;
       printf("desarchivage debut pour : %s\n taille de fichier_info : %lu", arch, sizeof(struct fichier_info));
       if( archive = open(arch, O_RDONLY)<0)
         {
           printf("archive impossible à lire");
         }
       lseek(archive,0,SEEK_SET);
       printf("\ntentative de read de l'archive :\n");
       if( read(archive,&et,sizeof(et)) == -1)
         {
         printf("erreur read desarchivage \n");
         }
       else
         {
           printf("nom fichier : %s \n",et.nom_file);
         }
     
    }
    Je veux juste extraire la première structure dans l'archive et afficher son nom. D'abord je mets bien le curseur au début du fichier pour être sur même si je pense qu'il doit déjà y être à la base, et puis après je tente le read. Je n'ai pas d'erreur à la compilation, mais à l'exécution mon programme se met en "pause". Cad le terminal affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    desarchivage debut pour : tr.mtr
     taille de fichier_info : 184
    tentative de read de l'archive :
    ^C
    Donc je dois faire ctrl+C pour arrêter le programme. J'ai aussi essayé avec fread et j'ai une erreur de segmentation. J'ai aussi tenté de rajouter des paramètres à open, mais je n'en vois pas un qui pourrait m'aider à lire le programme. J'ai déjà assigner des droits qui doivent me permettre d'ouvrir le fichier correctement dans ma fonction archive. Et le fichier existe bien et a le bon nombre d'octet (cad la taille de la structure + le contenu du fichier). Enfin bref je bloque encore sur un truc qui est sûrement encore tout bête

  19. #19
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    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 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zulhuky Voir le message
    J'ai un problème avec ma fonction désarchivage pour l'extraction de la structure, mon read ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       if( archive = open(arch, O_RDONLY)<0)
    Enfin bref je bloque encore sur un truc qui est sûrement encore tout bête
    Encore plus que tu ne le crois. L'erreur est sur cette seule et unique ligne. Je te laisse un peu chercher. Mais si tu arrives à me dire quel flux réel tu lisais (et pourquoi) je te mets un "+1"

    Sinon t'as raison à propos du lseek() inutile. Quand tu ouvres un fichier en mode "non append" t'es alors automatiquement au début.

  20. #20
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 163
    Points
    17 163
    Par défaut
    Ah oui, maintenant que tu le soulignes, c'est une chouette erreur.

Discussions similaires

  1. Ouvrir un fichier en mode binaire.
    Par _christophe_ dans le forum Général Python
    Réponses: 20
    Dernier message: 14/05/2008, 06h28
  2. Ecriture dans un fichier en mode binaire
    Par greg1517 dans le forum C
    Réponses: 14
    Dernier message: 11/02/2008, 17h35
  3. ouverture/lecture/ecriture dans un fichier en mode binaire
    Par dirty_boy dans le forum Débuter
    Réponses: 2
    Dernier message: 15/03/2006, 08h38
  4. [9.2.0.4 - forms 6i] Lire un fichier en mode RAW
    Par gaultier dans le forum Oracle
    Réponses: 3
    Dernier message: 30/01/2006, 11h11
  5. Réponses: 4
    Dernier message: 04/11/2005, 09h04

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