Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1353 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Probleme avec un Pipe

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Probleme avec un Pipe

n°1792776
elldekaa
dopa dopa !
Posté le 27-09-2008 à 14:45:38  profilanswer
 

Bonjour,
Je dois ecrire une programme qui lance 2 processus : 1 qui lit qq chose au clavier et qui l'envoie par la pipe (write) et l'autre qui recupere les caracteres a la sortie (read) et qui les affiche a l'ecran...
 

Code :
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. int main()
  7. {
  8. char *end = "$";
  9. int fd[2];
  10. pipe(fd);
  11. perror("Erreur (pipe): " );
  12. int p = fork();
  13. if(p!=0)
  14.  {
  15.  perror("Erreur (fork): " );
  16.  char tmp[10];
  17.  printf("Veuillez rentrer une suite de chaines de caracteres terminée par une chaine vide :" );
  18.  do
  19.   {
  20.   if(fgets(tmp,sizeof(tmp),stdin)==NULL) printf("erreur fgets" );
  21.   write(fd[1],tmp,strlen(tmp)+1);
  22.   perror("Erreur (write): " );
  23.   }while(strlen(tmp));
  24.  write(fd[1],tmp,sizeof(*tmp));
  25.  }
  26. if(p==0)
  27.  {
  28.  char tmp2[1];
  29.  do
  30.   {
  31.   if(read(fd[0],tmp2,1))
  32.    {
  33.    perror("Erreur (read): " );
  34.    printf(tmp2);
  35.    }
  36.   }while(strcmp(tmp2,end));
  37.  }
  38. }


 
 
j'ai le droit à cette magnifique erreur :
Erreur (write): : Invalid or incomplete multibyte or wide character
Erreur (read): : Illegal seek
Erreur (read): : Invalid or incomplete multibyte or wide character
Erreur (read): : Invalid or incomplete multibyte or wide character
Erreur (read): : Invalid or incomplete multibyte or wide character
 
que je ne comprends pas trop ... donc si quelqu'un aurait une idee ...
 
merci d'avance  :)  
 

mood
Publicité
Posté le 27-09-2008 à 14:45:38  profilanswer
 

n°1792794
elldekaa
dopa dopa !
Posté le 27-09-2008 à 16:40:20  profilanswer
 

j'ai améliorer un peu le truc :
 

Code :
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. int main()
  7. {
  8. char *end = "$";
  9. int fd[2];
  10. pipe(fd);
  11. perror("Erreur (pipe): " );
  12. int p = fork();
  13. if(p!=0)
  14.  {
  15.  close(fd[0]);
  16.  //perror("Erreur (fork): " );
  17.  char tmp[30];
  18.  //printf("Veuillez rentrer une suite de chaines de caracteres terminée par une chaine vide :" );
  19.  do
  20.   {
  21.   if(fgets(tmp,strlen(tmp),stdin)==NULL) printf("erreur fgets" );
  22.   int a = strlen(tmp);
  23.   printf("lg :%d",a);
  24.   write(fd[1],tmp,strlen(tmp));
  25.   perror("Erreur (write): " );
  26.   }while(strlen(tmp)!=1);
  27.  write(fd[1],end,strlen(end));
  28.  }
  29. if(p==0)
  30.  {
  31.  close(fd[1]);
  32.  char tmp2[2];
  33.  do
  34.   {
  35.   if(read(fd[0],tmp2,2))
  36.    {
  37.    perror("Erreur (read): " );
  38.    printf(tmp2);
  39.    }
  40.   }while(strcmp(tmp2,end));
  41.  }
  42. }


 
 
 
maintenant voilà l'erreur :
Erreur (pipe): : Success
lol
Erreur (write): : Illegal seek
lg :4Erreur (read): : Illegal seek
Erreur (read): : Invalid or incomplete multibyte or wide character
lo������p���Ŀ4��o��p��
plop
Erreur (write): : Illegal seek
Erreur (write): : Illegal seek
lg :3lg :2Erreur (read): : Invalid or incomplete multibyte or wide character
Erreur (read): : Invalid or incomplete multibyte or wide character
Erreur (read): : Invalid or incomplete multibyte or wide character
������p���Ŀ4��o��p���Ŀpl������p���Ŀ4��o��p���Ŀop������p���Ŀ4��o��p��
 
Erreur (write): : Illegal seek
lg :1ldk@LdK-virtualMachine:~/sgp$ Erreur (read): : Invalid or incomplete multibyte or wide character
p������p���Ŀ4��o��p��
 

n°1792798
ptitchep
Posté le 27-09-2008 à 17:59:58  profilanswer
 

elldekaa a écrit : a écrit :


Code :
  1. char tmp[30];
  2. ...
  3. fgets(tmp,strlen(tmp),stdin)






Le contenu de tmp n'est pas défini donc strlen(tmp) non plus. Essai avec fgets(tmp,30,stdin)en vérifiant avant dans le man comment est géré \0  par fgets, faudra peut-être mettre 29.
Prévois aussi un tampon plus grand pour la lecture avec toujours de la place pour \0.

Message cité 1 fois
Message édité par ptitchep le 27-09-2008 à 18:01:31

---------------
deluser --remove-home ptitchep
n°1792802
elldekaa
dopa dopa !
Posté le 27-09-2008 à 19:14:51  profilanswer
 

ptitchep a écrit :


Le contenu de tmp n'est pas défini donc strlen(tmp) non plus. Essai avec fgets(tmp,30,stdin)en vérifiant avant dans le man comment est géré \0  par fgets, faudra peut-être mettre 29.
Prévois aussi un tampon plus grand pour la lecture avec toujours de la place pour \0.


 
 
merci ça marche bien maintenant ...
juste un dernier soucis : je voudrais que les processus s'arrete lorsque une chaine vide est taper au clavier :
ma solution est d'envoyer dans le tube le caractere special "$" et ainsi arreter le processus fils ...
 
je voudrais trouver une solution plus propre (parce que actuellement si je rentre une chaine de caractere avec un "$" dedans le programme se termine.
donc si quelqu'un aurait une idee ...
 
 
 
 

Code :
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. int main()
  7. {
  8. char *end = "$"; // caractere "signal de fin"
  9. int tube[2];  // descripteur du tube
  10. if(pipe(tube)==-1) printf("erreur pipe" );
  11. //perror("Erreur (pipe): " );
  12. int p = fork();
  13. if(p==-1) printf("erreur fork" );
  14. if(p!=0)
  15.  {
  16.  close(tube[0]);
  17.  //perror("Erreur (fork): " );
  18.  char tmp[255];
  19.  printf("Veuillez rentrer une suite de chaines de caracteres terminée par une chaine vide : \n" );
  20.  do
  21.   {
  22.   if(fgets(tmp,255,stdin)==NULL) printf("erreur fgets" );
  23.   //int i = strlen(tmp);
  24.   //printf("lg: %d",i);
  25.   if(write(tube[1],tmp,strlen(tmp))==-1) printf("erreur write" );
  26.   }while(strlen(tmp)!=1);
  27.  if(write(tube[1],end,strlen(end))==-1) printf("erreur write" );
  28.  }
  29. if(p==0)
  30.  {
  31.  close(tube[1]);
  32.  char tmp2[1];
  33.  int tr;
  34.  while(strcmp(tmp2,end)!=0)
  35.   {
  36.   tr = read(tube[0],tmp2,1);
  37.   if(tr == -1) printf("erreur read" );
  38.   if(tr != 0) printf("%c",*tmp2);
  39.   }
  40.  }
  41. }

Message cité 1 fois
Message édité par elldekaa le 27-09-2008 à 19:19:38
n°1792824
ptitchep
Posté le 27-09-2008 à 20:35:26  profilanswer
 

Avec un signal?
 

Code :
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <signal.h>
  7. int main()
  8. {
  9.     int fd[2];
  10.     int p;
  11.     if(pipe(fd)==-1)
  12.         perror("Erreur (pipe): " );
  13.     p = fork();
  14.     if (p==-1)
  15.     {
  16.         perror ("Erreur (fork): ";);
  17.         return -1;
  18.     }
  19.     if(p!=0)
  20.     {
  21.         int a;
  22.         char tmp[30];
  23.         close(fd[0]);
  24.         printf("chaine:n" );
  25.         do
  26.         {
  27.             fgets(tmp,29,stdin);
  28.             a = strlen(tmp);
  29.              if(write(fd[1],tmp,a+1)==-1)
  30.                 perror("Erreur (write): " );
  31.         }while(a>1);
  32.         kill (p,SIGTERM);
  33.     }
  34.     else
  35.     {
  36.         char tmp2[30];
  37.         close(fd[1]);
  38.         while(1)
  39.         {
  40.             if(read(fd[0],tmp2,30)==-1)
  41.                    perror("Erreur (read): " );
  42.             printf(tmp2);
  43.         }
  44.     }
  45.     return 0;
  46. }


---------------
deluser --remove-home ptitchep
n°1792862
Sve@r
Posté le 27-09-2008 à 22:15:12  profilanswer
 

elldekaa a écrit :


ma solution est d'envoyer dans le tube le caractere special "$" et ainsi arreter le processus fils ...
 
je voudrais trouver une solution plus propre (parce que actuellement si je rentre une chaine de caractere avec un "$" dedans le programme se termine.
donc si quelqu'un aurait une idee ...


 
Ce genre de problème existe depuis la création de TCP/IP => comment signaler une fin sans que cette fin arrive "par erreur".
 
La solution la plus efficace est de donner un couple, par exemple "ab", qui signifie "arrêt".
Mais comment éviter de recevoir par erreur "ab" si par exemple l'émetteur envoie la chaine "abréviation" ? Ben tout simplement en dupliquant la lettre "a".
Donc si l'émetteur envoie "abréviation", le récepteur recevra "aabréviation". En lisant le premier "a" doublé il saura ce que c'est et enlèvera le "a" de trop. Mais s'il reçoit un simple "ab", alors cela voudra dire que c'est la fin.
 
Mécanisme primitif mais qui fonctionne tout le temps...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1792919
elldekaa
dopa dopa !
Posté le 27-09-2008 à 23:29:49  profilanswer
 

Sve@r a écrit :


 
Ce genre de problème existe depuis la création de TCP/IP => comment signaler une fin sans que cette fin arrive "par erreur".
 
La solution la plus efficace est de donner un couple, par exemple "ab", qui signifie "arrêt".
Mais comment éviter de recevoir par erreur "ab" si par exemple l'émetteur envoie la chaine "abréviation" ? Ben tout simplement en dupliquant la lettre "a".
Donc si l'émetteur envoie "abréviation", le récepteur recevra "aabréviation". En lisant le premier "a" doublé il saura ce que c'est et enlèvera le "a" de trop. Mais s'il reçoit un simple "ab", alors cela voudra dire que c'est la fin.
 
Mécanisme primitif mais qui fonctionne tout le temps...


 
j'imagine que ça doit bien fonctionner mais je ne vois pas comment l'appliquer dans mon cas vu que j'envoie chaque phrase en entier dans le pipe et que je recois caractere par caractere ...
j'vais quand meme y reflechir et de toute facon je garde ta méthode en memoire pour quand j'en aurais besoin ; )
merci !

n°1792924
elldekaa
dopa dopa !
Posté le 27-09-2008 à 23:59:42  profilanswer
 

ptitchep a écrit :

Avec un signal?


 
Marche nickel ! merci : )
 :D  

n°1792929
elldekaa
dopa dopa !
Posté le 28-09-2008 à 00:07:36  profilanswer
 

et dans le cas où ce ne sont pas 2 processus pere-fils (cad quand ils ne sont pas lancés dans le meme terminal) ??

n°1793017
matafan
Posté le 28-09-2008 à 13:15:04  profilanswer
 

C'est normal que tu ne teste pas le write avant de faire le perror ?

mood
Publicité
Posté le 28-09-2008 à 13:15:04  profilanswer
 

n°1793030
elldekaa
dopa dopa !
Posté le 28-09-2008 à 14:08:15  profilanswer
 

matafan a écrit :

C'est normal que tu ne teste pas le write avant de faire le perror ?


 
c'est fait dans la derniere version  ;)  

n°1793036
Sve@r
Posté le 28-09-2008 à 14:37:58  profilanswer
 

elldekaa a écrit :

j'imagine que ça doit bien fonctionner mais je ne vois pas comment l'appliquer dans mon cas vu que j'envoie chaque phrase en entier dans le pipe et que je recois caractere par caractere ...


Ben tu traites la phrase avant de l'envoyer et à la réception tu gères un cas particulier si tu reçois le caractère "a" (dans l'exemple "ab" )...

elldekaa a écrit :

et dans le cas où ce ne sont pas 2 processus pere-fils (cad quand ils ne sont pas lancés dans le meme terminal) ??


L'envoi d'un signal (kill()) marche aussi même sur des processus non liés père/fils. Faut juste que le processus qui envoie le signal connaisse le pid du processus cible (et aussi qu'il soit le propriétaire)...


Message édité par Sve@r le 28-09-2008 à 14:38:17

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1793207
matafan
Posté le 29-09-2008 à 09:30:53  profilanswer
 

Je vais peut-être dire une connerie (enfin je pense pas, mais bon), mais pour ton histoire de fermeture je ne comprend pas trop le problème. Quand le producteur détecte une ligne vide, il close() le pipe. Ca aura pour effet d'arrêter la lecture dans le consomateur (read() retourne 0).
 
Envoyer un truc spécial dans le pipe, ça ne se justifie que si tu veux une "connexion" persistante.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Probleme avec un Pipe

 

Sujets relatifs
Array crée a partir d'une bdd (probléme)...Problème De HTML et CSS
[Résolu] Problème avec une boucleTableau PHP en tableau javascript : Probleme
problème de conversionProbleme de disposition en CSS
[AJAX] Problème avec innerHTML=xhr_object.responseText[ASPX] [C#] Chercher et afficher une ligne dans un fichier Excel
Problème redirection .tkProblème d'insertion dans une table via une interface Visual C++
Plus de sujets relatifs à : [C] Probleme avec un Pipe


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR