espace dans une chaine de caractere [C] - Programmation
Marsh Posté le 27-03-2002 à 20:46:43
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
Marsh Posté le 27-03-2002 à 21:37:58
[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.
Marsh Posté le 27-03-2002 à 21:45:07
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
Marsh Posté le 27-03-2002 à 22:44:57
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 !
Marsh Posté le 28-03-2002 à 09:06:49
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 !?
Marsh Posté le 28-03-2002 à 09:10:50
El_Gringo a écrit a écrit : Mais... fgets, c pour lire à partir d'un fichier, par pour une saisie clavier... si !? |
Si, utilise stdin
Marsh Posté le 29-03-2002 à 19:32:34
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
Marsh Posté le 29-03-2002 à 19:57:55
fgets
Marsh Posté le 29-03-2002 à 20:00:58
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]
Marsh Posté le 29-03-2002 à 20:16:08
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]
Marsh Posté le 29-03-2002 à 20:18:33
Chaica, tu connais la commande man ?
man fgets
Code :
|
[jfdsdjhfuetppo]--Message édité par Jar Jar--[/jfdsdjhfuetppo]
Marsh Posté le 29-03-2002 à 20:19:13
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 !...
Marsh Posté le 29-03-2002 à 20:19:40
Jar Jar a écrit a écrit : Chaica, tu connais la commande man ? |
Ou son équivalent Windows, la touche magique "F1"
[jfdsdjhfuetppo]--Message édité par antp--[/jfdsdjhfuetppo]
Marsh Posté le 29-03-2002 à 23:06:19
Jar Jar : j'ai une no manual entry pour fgets. Il me manquerait quelque chose?
CHaiCA
Marsh Posté le 29-03-2002 à 23:10:41
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).
Marsh Posté le 29-03-2002 à 23:29:50
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
Marsh Posté le 29-03-2002 à 23:44:58
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 |
Marsh Posté le 29-03-2002 à 23:46:39
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]
Marsh Posté le 29-03-2002 à 23:57:11
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
Marsh Posté le 30-03-2002 à 00:01:10
À la réflexion, tu ne peux pas renvoyer une chaîne allouée localement.
Code :
|
Marsh Posté le 30-03-2002 à 03:32:51
==================================================
Code :
|
==================================================
A+,
[jfdsdjhfuetppo]--Message édité par gilou--[/jfdsdjhfuetppo]
Marsh Posté le 30-03-2002 à 10:05:45
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.
Marsh Posté le 30-03-2002 à 10:43:49
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]
Marsh Posté le 30-03-2002 à 11:46:01
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 :
|
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]
Marsh Posté le 30-03-2002 à 18:41:39
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 :
|
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 . realloc, c'est la moins secure de la famille malloc/calloc/realloc/free.
A+,
[jfdsdjhfuetppo]--Message édité par gilou--[/jfdsdjhfuetppo]
Marsh Posté le 30-03-2002 à 18:58:28
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 . 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 ?
Marsh Posté le 30-03-2002 à 19:47:11
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
Marsh Posté le 30-03-2002 à 19:54:40
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.
Marsh Posté le 30-03-2002 à 20:06:13
Bon c'est deja ca de corriger mais ca ne roule toujours pas.
hmm bon cherchons encore
CHaiCA
Marsh Posté le 30-03-2002 à 20:12:08
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.
Marsh Posté le 31-03-2002 à 03:36:11
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+,
Marsh Posté le 31-03-2002 à 12:22:42
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 ?
Marsh Posté le 01-04-2002 à 04:31:42
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+,
Marsh Posté le 01-04-2002 à 12:26:28
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.
Marsh Posté le 01-04-2002 à 12:57:45
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+,
Marsh Posté le 01-04-2002 à 13:35:58
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 |
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.
Marsh Posté le 01-04-2002 à 15:30:35
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+,
Marsh Posté le 27-03-2002 à 20:41:32
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