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 :

Problème tableau de chaînes de caratères


Sujet :

C

  1. #1
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut Problème tableau de chaînes de caratères
    Bonjour, je souhaiterais lire plusieurs lignes dans un fichier et les copier au fur et à mesure dans mon buffer.
    Mais le problème c'est que dans ma boucle while, là où je fais mon fgets, je ne sais pas quoi mettre pour que chaque saisie de fgets se fasse à la ligne suivante du tableau. Apparament buffer[i], ça ne marche pas.
    Pourriiez vous m'aidez s'il vous plait.

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
     
    #define TAILLE_LIGNE 32
    #define NB_LIGNES 60
     
     
    int read_x_lines(FILE *file, char **buffer, int x)
    {
      int nb_lignes_lues = 0;
      int i = 0;
     
      while((fgets(buffer[i],TAILLE_LIGNE,file))!= NULL && i<x)
      {
        nb_lignes_lues++;
        i++;
      }
     
      return nb_lignes_lues;
    }

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Normalement, cela doit fonctionner. Peut-on voir le reste de ton code (appel de read_x_lines et allocation mémoire pour le 2ème paramètre) ?

  3. #3
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
     
    #define TAILLE_LIGNE 32
    #define NB_LIGNES 60
     
    // lit x lignes et les place dans le buffer
    int read_x_lines(FILE *file, char **buffer, int x)
    {
      int nb_lignes_lues = 0;
      int i=0;
     
    	while((fgets(buffer,TAILLE_LIGNE,file))!= NULL && i<x)
    	{
    	  nb_lignes_lues++;
    	  i++;
    	}
     /*
      for(i=0;i<NB_LIGNES;i++)
        printf(" %s \n",buffer[i]);*/
     
      return nb_lignes_lues;
    }
     
    // crée un fils en lui transmettant une chaine de caractère qu'il devra afficher et écrire dans le fichier "filename"
    int create_new_child(char *text, char *filename)
    {
      pid_t fils;
      printf(" Creation du fils \n");
      fils = fork();
      switch(fils)
      {
        case -1 :
    	{
    	  perror(" fork ");
    	  exit(1);
    	}
    	case 0 :
    	{
    	  printf(" %s \n",text);
    	  FILE *fd = fopen(filename,"r");
    	  if(fwrite(text,sizeof(text), TAILLE_LIGNE, fd) == -1)
    	    perror(" write ");
    	  exit(0);
    	}
    	default :
    	{
    	  wait((int*)0);
    	  return fils;
    	}
     
      }
     
    }
     
     
    int *read_file_and_create_childs(char *srcname, char *dstname, int x, int nbprocs)
    {
      int i = 0;
      int p[12];
      int nbll;
      char **buffer;
      buffer = (char **)malloc(NB_LIGNES*sizeof(char *));
      for (i=0; i<NB_LIGNES; i++)
      {
       buffer[i] = (char*)malloc( sizeof(char*) * TAILLE_LIGNE);
      }
     
      FILE *file = fopen(srcname,"r");
     
       nbll = read_x_lines(file, buffer, srcname);
       while(i<x)
       {
         p[i] = create_new_child(buffer, dstname);
    	 i++;
       }
     
      return p;
    }
     
     
     
    int main(int argc, char **argv)	// argv[1] = n, argv[2] = fichier_source, argv[3] = fichier_destination
    {
      pid_t pid;
      int *PID;
     
      PID = read_file_and_create_childs(argv[2], argv[3], argv[1], 1);
     
     
     
    exit(0);
    }

    En fait ce que je veux c'est copier le texte par tranche de x lignes, ensuite créer un fils les lui transmettre pour qu'il les affiche et les écrive dans un fichier.
    Mon probleme c'est la manipulation de char **buffer;
    Rien que pour l'afficher ligne par ligne je ne sais pas comment faire.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    1ère remarque:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	  FILE *fd = fopen(filename,"r");
    	  if(fwrite(text,sizeof(text), TAILLE_LIGNE, fd) == -1)
    Tu ouvres le fichier en lecture et tu écris dedans ...

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    autre chose:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for (i=0; i<NB_LIGNES; i++)
      {
       buffer[i] = (char*)malloc( sizeof(char*) * TAILLE_LIGNE);  }
    buffer[i] contient au plus TAILLE_LIGNE caractères.


    Il suffit donc d'allouer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       buffer[i] = (char*)malloc( sizeof(char) * TAILLE_LIGNE);

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Enfin:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int read_x_lines(FILE *file, char **buffer, int x)
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FILE *file = fopen(srcname,"r");
     
       nbll = read_x_lines(file, buffer, srcname);
    D'un coté, tu déclares le 3ème paramètre de type int. De l'autre, tu transmets un char * lors de l'appel ...

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int *read_file_and_create_childs(char *srcname, char *dstname, int x, int nbprocs)
    le 3ème paramètre est de type int.

    et:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      PID = read_file_and_create_childs(argv[2], argv[3], argv[1], 1);
    argv[1] est de type char *.
    Tu dois transformer la chaîne de caractères en valeur numérique (par strtod ou atoi).

  8. #8
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Merci de m'avoir corrigé, par contre je ne fais pas bien la difference entre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    buffer[i] = (char*)malloc( sizeof(char*) * TAILLE_LIGNE);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    buffer[i] = (char*)malloc( sizeof(char) * TAILLE_LIGNE);
    A part l'étoile biensur.
    Dans les deux cas j'ai l'impression qu'on alloue une ligne de TAILE_LIGNE caractères.

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Autre chose: tu fais des fopen, jamais de fclose.
    La fin du processus entraîne la fermeture des fichiers ouverts mais quand même ...

    Surtout dans une fonction comme read_file_and_create_childs: si tu devais l'appeler de nombreuses fois, tu verrais ton fopen sortir en erreur au bout d'un moment.

    Bref, ajoute des fclose

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    sizeof(char) correspond à la taille en mémoire d'une variable de type char, soit 1 octet sur la plupart des systèmes.

    sizeof(char *) correspond à la taille d'une variable de type pointeur, soit 4 octets sur les micro-ordinateurs en général.

    Donc, l'instruction malloc( sizeof(char*) * TAILLE_LIGNE) alloue 4*TAILLE_LIGNE octets.

  11. #11
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Mais par un exemple double *, il serait egalement sur 4 octets ou sur 4*sizeof(double) octets?

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    sur la plupart (tous ?) les systèmes, on a:

    sizeof(char *) = sizeof(long *) = sizeof(double *) = sizeof(void *) (=4 sur les micros)

    Le compilateur ne distingue pas dans sa représentation interne les différents types de pointeurs.

  13. #13
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Ok je te remercie, mais pour en revenir à mon problème, dans quel but est-ce-que je dervais multiplier la capacité de ma ligne par 4?
    Parceque là le programme complie, mais ne m'affiche plus rien à l'éxecution, avant il m'affichait la dernière ligne seulement et indefiniment.

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Non, c'est le contraire. J'ai juste dit que la capacité de ta ligne était superflue (tu as alloué 4*NB_LIGNES octets alors que NB_LIGNE suffisaient).

    Une fois toutes les corrections apportées, si ton programme ne fonctionne toujours pas, reposte le ...

  15. #15
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Voilà le code, je pense avoir corrigé les erreurs que tu m'as indiquées.



    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
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
     
    #define TAILLE_LIGNE 32
    #define NB_LIGNES 60
     
    // lit x lignes et les place dans le buffer
    int read_x_lines(FILE *file, char **buffer, int x)
    {
      int nb_lignes_lues = 0;
      int i=0;
     
    	while((fgets(buffer[i],TAILLE_LIGNE,file))!= NULL && i<x)
    	{
    	  nb_lignes_lues++;
    	  i++;
    	}
     /*
      for(i=0;i<NB_LIGNES;i++)
        printf(" %s \n",buffer);*/
     
      return nb_lignes_lues;
    }
     
    // crée un fils en lui transmettant une chaine de caractère qu'il devra afficher et écrire dans le fichier "filename"
    int create_new_child(char *text, char *filename)
    {
      pid_t fils;
      printf(" Creation du fils \n");
      fils = fork();
      switch(fils)
      {
        case -1 :
    	{
    	  perror(" fork ");
    	  exit(1);
    	}
    	case 0 :
    	{
    	  printf(" %s \n",text);
    	  FILE *fd;
    	  if((fd=fopen(filename,"a")) == NULL);
    	    {
    		  perror(" fopen ");
    		  exit(1);
    	     }
     
    	  if(fwrite(text,strlen(text), 1, fd) == 0)
    	    {
    		  perror(" write ");
    		  exit(1);
    	     }
     
    	  fclose(fd);
    	  exit(0);
    	}
    	default :
    	{
    	  wait((int*)0);
    	  return fils;
    	}
     
      }
     
    }
     
     
    int *read_file_and_create_childs(char *srcname, char *dstname, int x, int nbprocs)
    {
      int i = 0;
      int p[12];
      int nbll;
     
      char **buffer;
      buffer = (char **)malloc(NB_LIGNES*sizeof(char ));
     
      for (i=0; i<NB_LIGNES; i++)
      {
       buffer[i] = (char*)malloc( sizeof(char) * TAILLE_LIGNE);
      }
     
      FILE *file = fopen(srcname,"r");
     
       nbll = read_x_lines(file, buffer, x);
     
       while(i<nbprocs)
       {
         p[i] = create_new_child(buffer[i], dstname);// ici j'ai mis buffer[i] mais je ne sais pas si la fonction va transmettre toute la ième ligne
    	 i++;
       }
     
      fclose(file); 
      return p;
    }
     
     
     
    int main(int argc, char **argv)	// argv[1] = n, argv[2] = fichier_source, argv[3] = fichier_destination
    {
      pid_t pid;
      int *PID;
      int n = atoi(argv[1]);
     
      PID = read_file_and_create_childs(argv[2], argv[3], n, 1);
     
    exit(0);
    }

  16. #16
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Cette fois, tu as un fclose en trop dans le read_x_lines.

  17. #17
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    dans le read_x_lines, toujours, il faut que tu fasses:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	while((fgets(buffer[i],TAILLE_LIGNE,file))!= NULL && i<x)

  18. #18
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Donc buffer[i] est bien la ième ligne de buffer.
    Mais pour quand je veux afficher les lignes de buffer dans un for et que j'utilise buffer[i] ça ne marche pas?
    // la boucle for est déjà en commentaire dans read_x_lignes

  19. #19
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    autre erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(fwrite(text,sizeof(text), TAILLE_LIGNE, fd) == -1)
    sizeof(text) vaut ici 4 car text est un char *. Je suppose que tu voulais plutôt faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fwrite(text,sizeof(char),TAILLE_LIGNE,fd)
    Mais d'un coté, tu utilises fwrite pour écrire des lignes de taille fixe, de l'autre, tu utilises fgets (qui lit des lignes terminées par '\n') pour lire.

    Ce n'est pas très cohérent.

  20. #20
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    J'ai remplacé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(fwrite(text,strlen(text), 1, fd) == 0)
    Qu'en penses tu?

Discussions similaires

  1. Réponses: 10
    Dernier message: 10/01/2014, 16h12
  2. Problème tableau de chaînes de caratères
    Par developppez dans le forum C
    Réponses: 4
    Dernier message: 07/05/2007, 20h33
  3. [perl]Problème tableau indexé
    Par LE NEINDRE dans le forum Langage
    Réponses: 8
    Dernier message: 25/08/2005, 21h24
  4. Problème de type chaîne
    Par champijulie dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 12/05/2005, 20h23
  5. [CR8] Problème tableau sur plusieurs pages???
    Par christophe28 dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 02/11/2004, 15h46

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