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

 


Dernière réponse
Sujet : [C] espace dans une chaine de caractere
gilou Vi sauf que ce qu'ils disent pas chez HP, c'est que la lib pthreads est pas installée par defaur, ni les includes...
Bon, je pense qu'on peut arreter ce sujet, qui a devie a un point tel qu'on pourrait se croire sur BlaBla.
A+,

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
gilou Vi sauf que ce qu'ils disent pas chez HP, c'est que la lib pthreads est pas installée par defaur, ni les includes...
Bon, je pense qu'on peut arreter ce sujet, qui a devie a un point tel qu'on pourrait se croire sur BlaBla.
A+,
Jar Jar

gilou a écrit a écrit :

 
Ca en fait pas qque chose de standard. Je te repete que ni visual C++, ni vacpp sur AIX n'ont l'air de connaitre, et je peux verifier sur HP-UX si necessaire.


En farfouillant (pas longtemps) sur Google, voilà ce que j'ai trouvé :

Citation :

> > 2) Aix doesn't seem to define either _PTHREADS or _REENTRANT.  How
> > does gthr.h include the right header for posix threads?
> > I don't understand this completely myself.  As far as I know, AIX is
> multilib'd in a way that it builds against the correct version of
> gcc/gc/gthr-*.h in each path.
 
The HPUX implementation is similar to that for AIX.  The build automatically
adds `-threads' when building the threaded libraries.  This also gives
the correct defines and linking.  You don't have to do anything special
for these systems.

Conclusion, il ne connaît pas _REENTRANT, mais si tu le définis tout marchera correctement partout (sauf probablement avec VC++, mais on s'en fout, car ce n'est pas un vrai compilateur C).
 
Enfin on s'écarte pas mal du sujet, puisque contrairement à ce que je pensais ça ne change pas la façon d'allouer les tableaux statiques.

gilou

Jar Jar a écrit a écrit :

Sisi, c'est standard. Ça marche au moins avec Sun CC et GCC.
Par contre, après vérification, il ne change pas l'allocation statique de tes fonctions, mais il se contente de choisir des fonctions de bibliothèque réentrantes.  




Ca en fait pas qque chose de standard. Je te repete que ni visual C++, ni vacpp sur AIX n'ont l'air de connaitre, et je peux verifier sur HP-UX si necessaire.
Le produit sur lequel je bosse a un code compilable (sauf qques parties dependantes de l'implem de la librairie graphique et de la boucle evenementielle) sur Windows, Mac, Sun, HP-UX et AIX (avec selon les plateformes, du compilo natif ou un mix de natif et de librairies compilees avec gcc/g++) alors ce genre de notions (flag standard), est tres important pour ma pratique.
A+,

Jar Jar

gilou a écrit a écrit :

C'est un symbole defini sans doute pour un compilo precis, pas l'air d'etre connu de mon compilo sur AIX par exemple, ou pour VC++. Donc inutilisable pour faire du code portable, et pas standard.


Sisi, c'est standard. Ça marche au moins avec Sun CC et GCC.
Par contre, après vérification, il ne change pas l'allocation statique de tes fonctions, mais il se contente de choisir des fonctions de bibliothèque réentrantes.

gilou

Jar Jar a écrit a écrit :

T'es sûr ? Même en compilant en -D_REENTRANT ?  




 
C'est un symbole defini sans doute pour un compilo precis, pas l'air d'etre connu de mon compilo sur AIX par exemple, ou pour VC++. Donc inutilisable pour faire du code portable, et pas standard.
A+,

Jar Jar

gilou a écrit a écrit :

Euh, au fait, non, en C, une variable statique est allouée une fois pour toute dans un programme (a priori dans le bss [block starting segment]) dans le cas precis de mon exemple.  
A+,


T'es sûr ? Même en compilant en -D_REENTRANT ?

gilou

Jar Jar a écrit a écrit :

Primo, j'utilise un buffer statique, donc alloué a la compil, et si la fonction est utilisee n fois, j'ai pas besoin de faire plusieurs fois un malloc d'une taille inutile.
Non, il sera alloué sur le tas à chaque appel à ta fonction.




Euh, au fait, non, en C, une variable statique est allouée une fois pour toute dans un programme (a priori dans le bss [block starting segment]) dans le cas precis de mon exemple.  
A+,

Jar Jar

chaica a écrit a écrit :

Bon c'est deja ca de corriger mais ca ne roule toujours pas.
hmm bon cherchons encore :D


Tu as mis sizeof(sujet) alors que c'est une chaîne allouée dynamiquement. Il faut plutôt déclarer une constante TOTO, faire un malloc(TOTO), et réutiliser TOTO dans le fgets.

chaica Bon c'est deja ca de corriger mais ca ne roule toujours pas.
hmm bon cherchons encore :D
 
CHaiCA
Jar Jar Il faut vraiment éviter strcpy quand on ne sait pas ce qu'on fait (donc pour les newbies, c'est proscrit).
 
Avec ta routine, la valeur renvoyée est allouée avec malloc, donc pas besoin de la recopier ailleurs.
 
Il vaut mieux mettre :
sujet_fin=suj();
printf("%s",sujet_fin);
free(sujet_fin); // À chaque malloc DOIT correspondre un free.
HappyHarry ben si tu alloues pas sujet_fin ...
chaica Bon me revoilà, voila où j'en suis
 
#include <stdio.h>
#include <stdlib.h>
#include <fonctions.h>
 
 
 
char *suj()
{
  char *sujet;
   
  sujet=malloc(1000);
 
  printf("Saisissez le sujet du mail:\n" );
  fgets(sujet,sizeof(sujet),stdin);
 
  return sujet;
   
     
}
 
#include <stdio.h>
#include <fonctions.h>
 
   
int main()
{
   
  char *sujet_fin;
 
strcpy(sujet_fin,suj());
printf("%s",sujet_fin);
 
return 0;
 
(je ne copie que les bouts du programme concernant notre sujet) et bon maintenant j'ai un segmentation default.
 
CHaiCA
Jar Jar

gilou a écrit a écrit :

Quand a realloc, par experience je l'evite car:
Tu n'est pas sur qu'il ne vas pas bouger tes données (ca peut arriver). Il peut en effet juste diminuer son descripteur interne, mais pas necessairement, ca depend de l'allocateur/gestionnaire memoire qui peut avoir son mot a dire sur la fragmentation induite.
De plus, j'ai connu des cas ou cette fonction ne marchait pas correctement sur un Unix que je ne nommerais pas :D. realloc, c'est la moins secure de la famille malloc/calloc/realloc/free.


Bah en utilisant realloc, tu n'es pas sûr qu'il ne va pas bouger les données, alors qu'avec ton tampon tu es sûr qu'il va les bouger, donc le choix est vite fait... Et puis je ne voudrais pas avoir à développer sur l'unix que tu viens de citer, tu fais comment sans realloc pour faire des tableaux à taille variable ?

gilou

Jar Jar a écrit a écrit :

Primo, j'utilise un buffer statique, donc alloué a la compil, et si la fonction est utilisee n fois, j'ai pas besoin de faire plusieurs fois un malloc d'une taille inutile.
Non, il sera alloué sur le tas à chaque appel à ta fonction.
 
Secondo, le strdup va faire un malloc, mais juste de la taille necessaire a contenir la chaîne, contrairement a ton cas.
Oui, c'est pour ça que je suggère un :

Code :
  1. sujet=malloc(BOARF);       
  2. printf("Saisissez le sujet:\n" );                                             
  3. fgets(sujet,BOARF,stdin);                                                     
  4. return realloc(sujet,strlen(sujet)+1);


Je pense que c'est plus efficace qu'un strdup, car les données ne seront pas déplacées lors du realloc.
 :non:  
Ben si tu relis mon code, tu verras que je fais: if (sujet = getSubject()) et donc que lorsque je fais le free, le pointeur n'est pas NULL.
Oups, j'avais mal lu, désolé.  
 
 




Bon OK, je met le buffer en variable globale et on en parle plus ;)
 
Quand a realloc, par experience je l'evite car:
Tu n'est pas sur qu'il ne vas pas bouger tes données (ca peut arriver). Il peut en effet juste diminuer son descripteur interne, mais pas necessairement, ca depend de l'allocateur/gestionnaire memoire qui peut avoir son mot a dire sur la fragmentation induite.
De plus, j'ai connu des cas ou cette fonction ne marchait pas correctement sur un Unix que je ne nommerais pas :D. realloc, c'est la moins secure de la famille malloc/calloc/realloc/free.
A+,

 

[jfdsdjhfuetppo]--Message édité par gilou--[/jfdsdjhfuetppo]

Jar Jar Primo, j'utilise un buffer statique, donc alloué a la compil, et si la fonction est utilisee n fois, j'ai pas besoin de faire plusieurs fois un malloc d'une taille inutile.
Non, il sera alloué sur le tas à chaque appel à ta fonction.
 
Secondo, le strdup va faire un malloc, mais juste de la taille necessaire a contenir la chaîne, contrairement a ton cas.
Oui, c'est pour ça que je suggère un :

Code :
  1. sujet=malloc(BOARF);       
  2. printf("Saisissez le sujet:\n" );                                             
  3. fgets(sujet,BOARF,stdin);                                                     
  4. return realloc(sujet,strlen(sujet)+1);


Je pense que c'est plus efficace qu'un strdup, car les données ne seront pas déplacées lors du realloc.
 
Ben si tu relis mon code, tu verras que je fais: if (sujet = getSubject()) et donc que lorsque je fais le free, le pointeur n'est pas NULL.
Oups, j'avais mal lu, désolé.

 

[jfdsdjhfuetppo]--Message édité par Jar Jar--[/jfdsdjhfuetppo]

gilou

Jar Jar a écrit a écrit :

Gni ? C'est string.h, sous Unix.
Oui, desole, j'ai lu trop vite la man page, laquelle faisait reference a strings.h pour les strncasecmp et a string.h pour le reste ensuite. Je vais editer mon post.
 
Et c'est quoi l'intérêt du strdup, dans le cas qui nous concerne ? Quitte à allouer deux fois, autant utiliser realloc.
Primo, j'utilise un buffer statique, donc alloué a la compil, et si la fonction est utilisee n fois, j'ai pas besoin de faire plusieurs fois un malloc d'une taille inutile.
Secondo, le strdup va faire un malloc, mais juste de la taille necessaire a contenir la chaîne, contrairement a ton cas.

Au passage, c'est encore mal, car sur de nombreux systèmes free(NULL) fait un segfault.  
Ben si tu relis mon code, tu verras que je fais: if (sujet = getSubject()) et donc que lorsque je fais le free, le pointeur n'est pas NULL.



 

[jfdsdjhfuetppo]--Message édité par gilou--[/jfdsdjhfuetppo]

Jar Jar

gilou a écrit a écrit :

 
[code]#ifdef WIN32
    #include <string.h>
    #include <stdio.h>
    #include <malloc.h>
    #define  strdup(x)     _strdup(x)
#else /* UNIX */
    #include <strings.h>
    #include <stdio.h>
    #include <stdlib.h>
#endif


Gni ? C'est string.h, sous Unix.
Et c'est quoi l'intérêt du strdup, dans le cas qui nous concerne ? Quitte à allouer deux fois, autant utiliser realloc.
 
Au passage, c'est encore mal, car sur de nombreux systèmes free(NULL) fait un segfault.

gilou ==================================================

Code :
  1. #include <string.h>
  2. #include <stdio.h>
  3. #ifdef WIN32
  4.     #include <malloc.h>
  5.     #define  strdup(x)     _strdup(x)
  6. #else /* UNIX */
  7.     #include <stdlib.h>
  8. #endif
  9. #define BUFFSIZE 1024
  10. char *getSubject(void)
  11. {
  12.     static char workBuff[BUFFSIZE];
  13.     printf("Saisissez le sujet:\n" );
  14.     if (fgets(workBuff, sizeof(workBuff), stdin))
  15.         return strdup(workBuff);
  16.     else
  17.         return NULL;
  18. int main(int argc, char **argv)
  19. {
  20.     char *sujet;
  21.     if (sujet = getSubject())
  22.     {
  23.         if ((!*sujet) || (*sujet == '\n'))
  24.             printf("Pas de sujet.\n" );
  25.         else
  26.             printf("Sujet: %s", sujet);
  27.         free(sujet);
  28.         return(0);
  29.     }
  30.     else
  31.     {
  32.         printf("Pas de sujet.\n" );
  33.         return(-1);
  34.     }
  35. }


==================================================
A+,

 

[jfdsdjhfuetppo]--Message édité par gilou--[/jfdsdjhfuetppo]

Jar Jar À la réflexion, tu ne peux pas renvoyer une chaîne allouée localement.
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. char *suj()
  4. {
  5. char *sujet;
  6. sujet=malloc(1000);
  7.                                                                              
  8. printf("Saisissez le sujet:\n" );                                             
  9. fgets(sujet,1000,stdin);                                                     
  10.                                                                              
  11. return sujet;                                                               
  12.                                                                              
  13. }                                                                             
  14.                                                                              
  15. int main(int argc, char **argv)                                               
  16. {                                                                             
  17. char *toto;                                                                 
  18.                                                                              
  19. toto=suj();
  20. printf("%s",toto);
  21. free(toto);
  22. return 0;
  23. }

chaica hmm j'ai essayé vos deux solutions et ca marche pas.
 
Eest ce qu'il y a quelque chose à faire autour de stdin, il faut le déclarer quelque part?
 
CHaiCA
[SDF]Poire ou :
 
char *suj()
{
 char sujet[1000];
 
 printf("Saisissez le sujet:\n" );
 fgets(sujet,1000 * sizeof(char),stdin);
   
 return sujet;
   
}

 

[jfdsdjhfuetppo]--Message édité par [SDF]Poire--[/jfdsdjhfuetppo]

Jar Jar

chaica a écrit a écrit :

Bon je vais encore faire chier mais ca plante. Pourtant je n'ai rien lors de la compilation. j'affiche ma fonction
 
char *suj()
{
  char sujet[1000];
   
  printf("Saisissez le sujet:\n" );
  fgets(sujet,1000,stdin);
     
  return sujet;
     
}
 
hmm très cool
 
CHaiCA  



chaica Bon je vais encore faire chier mais ca plante. Pourtant je n'ai rien lors de la compilation. j'affiche ma fonction
 
char *suj()
{
  char sujet[1000];
   
  printf("Saisissez le sujet:\n" );
  fgets(sujet,sizeof(1000),stdin);
     
  return sujet;
     
}
 
hmm pas cool
 
CHaiCA
Jar Jar

chaica a écrit a écrit :

Jar Jar : j'ai une no manual entry pour fgets. Il me manquerait quelque chose?


Oui, les pages de manuel de développement. Sous Debian, ça s'appelle manpages-dev (et manpages-fr pour la traduction).

chaica Jar Jar : j'ai une no manual entry pour fgets. Il me manquerait quelque chose?
 
CHaiCA
antp

Jar Jar a écrit a écrit :

Chaica, tu connais la commande man ?




 
Ou son équivalent Windows, la touche magique "F1" :D

 

[jfdsdjhfuetppo]--Message édité par antp--[/jfdsdjhfuetppo]

torpe23 t'es une putain de larve toi !  
 
T'as 9 messages et t'arrive pas à faire ce que tu veux avec ça !  
Si on te dis fgets, c'est que c'est fgets !  
Et fgets, si tu te renseignais un peu sur cette fonction ( car l'aide de ton logiciel existe ! ), tu connaitrais ses arguments :
char * fgets (char * s, int n, FILE * fic);  
 
Dans ton cas : fgets(chaine,nombre_de_caracteres,stdin);
 
sinon c'est scanf("%[^\n]s",chaine), mais celui ci, je l'avais déja mis 3 messages plus haut !...
Jar Jar Chaica, tu connais la commande man ?
 
man fgets

Code :
  1. NOM
  2.        gets, fgetc, fgets, getc, getchar, ungetc - Saisie de car­
  3.        actères et de chaînes.
  4. SYNOPSIS
  5.        #include <stdio.h>
  6.        char *fgets (char *s, int size, FILE *stream);
  7. DESCRIPTION
  8.        fgets()  lit  au plus size - 1 caractères depuis stream et
  9.        les place  dans  le  buffer  pointé  par  s.   La  lecture
  10.        s'arrête  après  EOF  ou  un retour-chariot. Si un retour-
  11.        chariot (newline) est lu, il est placé dans le buffer.  Un
  12.        caractère nul '\0' est placé à la fin de la ligne.
  13. VALEUR RENVOYÉE
  14.        gets()  et  fgets()  renvoient  le  pointeur  s  si  elles
  15.        réussissent, et NULL en cas d'erreur,  ou  si  la  fin  de
  16.        fichier  est  atteinte  avant  d'avoir pu lire au moins un
  17.        caractère.
  18. BOGUES
  19.        N'utilisez jamais gets().   Comme  il  est  impossible  de
  20.        savoir  à  l'avance  combien  de caractères seront lus par
  21.        gets(), et comme celui-ci écrira tous les caractères  lus,
  22.        même   s'ils  débordent  du  buffer,  cette  fonction  est
  23.        extrèmement dangereuse à utiliser. On a  déjà  utilisé  ce
  24.        dysfonctionnement   pour  créer  des  trous  de  sécurité.
  25.        UTILISEZ TOUJOURS fgets() A LA PLACE DE gets().
  26. VOIR AUSSI
  27.        read(2), write(2), fopen(3), fread(3), scanf(3),  puts(3),
  28.        fseek(3), ferror(3)
  29. TRADUCTION
  30.        Christophe Blaess, 1997.

 

[jfdsdjhfuetppo]--Message édité par Jar Jar--[/jfdsdjhfuetppo]

antp fgets(ma_chaine, sizeof(ma_chaine), stdin);
 
Et je confirme que fgets c'est la meilleure solution "C standard" pour lire des chaînes. Le sizeof(ma_chaine) empêche un dépassement de buffer, chose que gets ne fait pas il me semble.

 

[jfdsdjhfuetppo]--Message édité par antp--[/jfdsdjhfuetppo]

chaica J'entre fgets(machaine) et ca marche pas. fgets ca ne doit pas lire une fichiner moi je veux l'équivalent d'un scanf("%s",machaine) mais qui puisse aussi stocker les espaces.  
 
CHaiCA

 

[jfdsdjhfuetppo]--Message édité par chaica--[/jfdsdjhfuetppo]

Jar Jar fgets
chaica Je me permets de reposer ma question parce qu'il semble qu'on se soit égaré :
 
Quelle commande utiliser pour saisir une chaine de caractere avec les espaces (je veux en fait que l'utilisateur du programme entre une phrase.) ?
 
CHaiCA
cycojesus

El_Gringo a écrit a écrit :

 
 
Mais... fgets, c pour lire à partir d'un fichier, par pour une saisie clavier... si !?  




 
Si, utilise stdin

El_gringo

Jar Jar a écrit a écrit :

JAMAIS !!!!!
On utilise fgets, et rien d'autre. Ah si, readline c'est bien, mais c'est une extension GNU.  




 
Mais... fgets, c pour lire à partir d'un fichier, par pour une saisie clavier... si !?

torpe23 il y a aussi scanf("%[^\n]s",...) pour prendre tous les caractères sauf le retour chariot. Ne pas oublier le        fflush(stdin) pour vider le tampon afin qu'il n'y ait pas d'erreurs !
[SDF]Poire

Jar Jar a écrit a écrit :

JAMAIS !!!!!
On utilise fgets, et rien d'autre. Ah si, readline c'est bien, mais c'est une extension GNU.  




Oui C ce que je voulais dire  :D

Jar Jar

[SDF]Poire a écrit a écrit :

utilise gets


JAMAIS !!!!!
On utilise fgets, et rien d'autre. Ah si, readline c'est bien, mais c'est une extension GNU.

[SDF]Poire

chaica a écrit a écrit :

Lors d'une saisie d'une chaine de caractere, les espaces font interrompre la saisie au premier mot qui precede l'espace. Comment peut on faire pour que la chaine soit enregistre entierement AVEC les espaces?
 
CHaiCA  




avec scanf C normal
utilise gets

chaica Lors d'une saisie d'une chaine de caractere, les espaces font interrompre la saisie au premier mot qui precede l'espace. Comment peut on faire pour que la chaine soit enregistre entierement AVEC les espaces?
 
CHaiCA

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)