[C] pointeur sur chaîne de caractères

Fermé
Onde2Choc Messages postés 299 Date d'inscription vendredi 6 août 2004 Statut Membre Dernière intervention 24 février 2006 - 21 août 2004 à 18:03
SmallFitz Messages postés 351 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 21 juin 2013 - 7 nov. 2007 à 19:03
Dans mon long apprentissage du langage C, je suis rendu manipulations de chaînes de caractères avec des pointeurs (chapitre 10/21). Voilà un extrait de code donné en exemple pour contrôler une ligne blanche avec gets() :
while( *(pointeur = gets(input)) != NULL)
{ (instructions) } 
/*reste du programme*/

Mais quand j'entre ces mêmes lignes dans mon compilateur, Dev C++, le compilo lui même ne dis rien mais quand je lance le programme ça cause une erreur ("Le système à repéré une erreur sérieuse. Voulez-vous envoyer le journal etc..."). Est-ce grave docteur ? D'où ça vient ?


BOOM !
Laissez se propager l'onde de choc...
A voir également:

21 réponses

C'est quoi les instructions (instructions) a l'intérieur de ta boucle.
Si tu nous fil le code on comprendra peut-être un peu mieux.

"There are only 10 types of peoples in the world : Those who understand binary and those who don't."
0
On peut avoir le main ou c'est trop long? Le pointeur il pointe sur un autre pointeur?

*(pointeur) pour moi c'est la valeur pointé qui doit être égale à un pointeur NULL
0
Hello !

Règle de base :
il ne faut jamais utiliser un pointeur sans le vérifier au préalable.

Le code correct est donc :

while( (pointeur = gets(input)) == NULL)
{
printf("Vous n'avez pas entré de chaîne. Alors cette fois écris quelque chose : ");
}
/*reste du programme*/
0
Onde2Choc Messages postés 299 Date d'inscription vendredi 6 août 2004 Statut Membre Dernière intervention 24 février 2006 4
22 août 2004 à 08:39
J'ai testé le même code sur mon win98 et il fonctionne parfaitement... En effet guki c'est la valeur de l'adresse pointée qui doit être nulle, ce qui est le cas lorsque tu entres une ligne blanche : le pointeur pointe sur un caractère nul.
Par contre Jolkdarr, le pointeur de ton code, tel que tu l'utilises, est juste initialisé pour pointer sur input, et c'est l'adresse mémoire qui va être testée... Or comme le caractère nul est tout de même stocké en mémoire, ce test donnera toujours 0, c'est à dire que le while ne fonctionnera jamais. Voila les instructions d'initialisations :
char input[256], *pointeur = input;
Pour la version de mon win98 et
char input[256], *pointeur;
pointeur = input;
Pour la version winXP, j'ai raccourci le tout sur mon win98. input étant un pointeur vers input[0], seule l'adresse mémoire intéresse le pointeur donc pas de "*" devant pointeur.

Pour Kilian et Guki, une seule chose à dire : tschhh... hoooo... tschh.... hooooo.... :-) la patience n'est pas la 1ere de mes qualités dans certaines situations !

BOOM !
Laissez se propager l'onde de choc...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bon si je reprend les bouts d'information:

char input[256];
char *pointeur;

pointeur = &input[0];
while( *(pointeur = gets(input)) == NULL)
{
printf("Vous n'avez pas entré de chaîne. Alors cette fois écris quelque chose : ");
gets(phrase);
}

donc *(pointeur) est la valeur pointée donc un char qui devrait être égale à un pointeur (adresse) NULL soit en entier 32 bits sur un CPU 32 bits qui contient le nombre 0 je crois que ça pose problème au niveau de la comparaison.
0
Onde2Choc Messages postés 299 Date d'inscription vendredi 6 août 2004 Statut Membre Dernière intervention 24 février 2006 4
22 août 2004 à 10:00
Si ça peut aider, mon tapis de souris est rouge.


BOOM !
Laissez se propager l'onde de choc...
0
Ravachol Messages postés 566 Date d'inscription vendredi 5 mars 2004 Statut Membre Dernière intervention 30 octobre 2005 120
22 août 2004 à 10:07
Ben voila l'erreur ... gets ne fonctionne qu'avec des tapis bleu sous zindozs.

La pensée ne commence qu'avec le doute.
ROGER MARTIN DU GARD
0
Remplace NULL par 0 pour voir.
0
Hello !

Manifestement, je n'ai pas été assez clair. Je répète donc :
Règle : NE JAMAIS UTILISER UN POINTEUR SANS LE TESTER.

gets() renvoie un pointeur NULL si un problème est rencontré (comme lecture d'un EOF par exemple). Il faut donc absolument tester le pointeur avant toute utilisation.

Exemple de code qui marche sauf dans le cas où le pointeur renvoyé est NULL (par exemple, tapez CTRL+D sous linux au moment d'entrer la chaîne => segmentation fault):

#include <stdio.h>

int main(int N, char * A[])
{
char input[500];
char* pointeur;

while (*(pointeur = gets(input)) == '\0')
{
printf("Entrez une chaine svp.\n");
}

printf("Vous avez entre %s\n", input);

return 0;
}


Exemple de code qui marche dans tous les cas (même quand on entre CTRL+D) :

#include <stdio.h>

int main(int N, char * A[])
{
char input[500];
char* pointeur;

/* test du pointeur avant son utilisation (obligatoire!) */
while ((pointeur = gets(input)) == NULL || *pointeur == '\0')
{
printf("Entrez une chaine svp.\n");
}

printf("Vous avez entre %s\n", input);

return 0;
}


J'espère que c'est plus clair cette fois.

Take care !
0
Pour mémoire :

#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif

Si le compilateur n'a rien dit, c'est qu'il a compilé en tant que compilateur C++ et non C. Par conséquent, changer NULL par 0 ne changera rien car c'est déjà la valeur de la macro.

Take care !
0
Ah bon parce que C++ implémente différemment NULL je croyais que la base était le C faudrait qu'on m'explique.

ISO/IEC 14882:1998
20.4.6
...
Header <cstring>
The contents are the same as the Standard C library header <string.h>, ...

Bien essayé quand même. ;-)
0
Bon j'ai parlé trop vite ça m'apprendra effectivement C++ ne fait pas la même chose ce qui semble étrange tout de même.

PS: pas taper merci.
0
Hot Metal Messages postés 7 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 23 août 2004
22 août 2004 à 14:31
Salut

Ne jamais utiliser gets(); mais plutot fgets();.

extrait du man de linux.
N'utilisez jamais gets().  Comme il est impossible de savoir à l'avance
       combien de caractères seront lus par gets(), et comme  celui-ci  écrira
       tous les caractères lus, même s'ils débordent du buffer, cette fonction
       est extrèmement dangereuse à utiliser. On a déjà  utilisé  ce  dysfonc-
       tionnement pour créer des trous de sécurité.  UTILISEZ TOUJOURS fgets()
       A LA PLACE DE gets().


Pour le probleme
#include <stdio.h> 
 
int main(int N, char * A[]) 
{ 
 char input[500]; 
 
 memset(input,0,sizeof(input));
 do
 { 
   printf("Entrez une chaine svp.\n"); 
   fgets(input,sizeof(input),stdin);

 /* verifie si un valeur est dans input, le /r pour win32 seulement */
 } while ((input[0] == 0) || (input[0] == '/n') || (input[0] == '/r')) ;
 
 printf("Vous avez entre %s\n", input); 
 
 return 0; 
} 
0
Hello !

Ce programme ne "plante" pas car on n'utilise pas de pointeur initialisé avec la valeur retournée par fgets. Le problème cette fois, c'est que la fonction fgets n'élimine pas les espaces comme le fait gets. Par exemple, si on l'utilisateur ne rentre pas de chaîne et tape des espaces avant de faire RETURN, il voit le message suivant :

Vous avez entre

=> à reprendre un peu...

Autre remarques :
a) Avec les vieux compilateurs pre-ANSI C, il n'était pas toujours possible de fournir des "initialisateurs" pour les tableaux locaux définis dans les fonctions. Seule l'initialisation de tableaux globaux (tableaux définis à l'extérieur de toute fonction) était possible. Ces compilateurs étant rares, il n'est plus la peine de s'inquiéter et on peut alors écrire (si on veut) :

char input[500] = { 0 };

pour initialiser le tableau sans utiliser la fonction memset.

b) le compte-rendu retourné par la fonction n'est jamais testé (on risque une boucle infinie). Il est préférable de le faire comme dans l'exemple suivant fourni par Microsoft pour l'API du système Windows :

/* This program uses fgets to display * a line from a file on the screen. */
#include <stdio.h>

int main( void )
{
FILE *stream;
char line[100];

if( (stream = fopen( "crt_fgets.txt", "r" )) != NULL )
{
if ( fgets( line, 100, stream ) == NULL)
printf( "fgets error\n" );
else printf( "%s", line);
fclose( stream );
}
}
0
J'oubliais :

Remarque très importante :
Ecrire '\n' et '\r' et non '/n', '/r'.
Ca marchera mieux... ;)

Take care !
0
Hot Metal Messages postés 7 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 23 août 2004
23 août 2004 à 00:35
Oups petite erreur :)
0
Au temps pour moi, gets n'élimine pas les espaces non plus...
Faut les filtrer si on ne les veut pas.
0
Onde2Choc Messages postés 299 Date d'inscription vendredi 6 août 2004 Statut Membre Dernière intervention 24 février 2006 4
23 août 2004 à 08:50
Oula... fgets(), FILE, fopen, fclose... tout ça j'ai pas encore vu ! Je suis qu'un simple débutant : je viens de terminer le chapitre sur les structures et de commencer celui sur la portée des variables. Mais sinon j'ai copié collé vos codes et ils fonctionnent.


BOOM !
Laissez se propager l'onde de choc...
0
amjedinho Messages postés 1 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 7 novembre 2007
7 nov. 2007 à 17:48
slt tout le monde .
je dois ecrire un programme en c qui lit une phrase puis range chaque dans un tableau de chaine (les caracteres des mots sont copiés un par un dans une case de tableau ).
svp aidez cé urgent
0
SmallFitz Messages postés 351 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 21 juin 2013 185
7 nov. 2007 à 19:03
Salut !
Crée ton propre topic, celui ci semble être terminé (il date de Août donc bon... ;D !)
0
Onde2Choc Messages postés 299 Date d'inscription vendredi 6 août 2004 Statut Membre Dernière intervention 24 février 2006 4
21 août 2004 à 19:08
Personne d'assez cultivé et sympa à la fois pour me répondre ?


BOOM !
Laissez se propager l'onde de choc...
-1
Onde2Choc Messages postés 299 Date d'inscription vendredi 6 août 2004 Statut Membre Dernière intervention 24 février 2006 4
21 août 2004 à 19:33
Il y en a qui connaissent le C ici ou me*de ?


BOOM !
Laissez se propager l'onde de choc...
-1
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
21 août 2004 à 21:45
On est sensés rappliquer au garde à vous??? :-|

Kilian, débutant en tâche de fond.....
0
Guki > kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016
21 août 2004 à 21:51
Je crois que l'impatience l'a fait virer dans le dark side ce qui n'arrangera pas ses affaires. ;-)
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527 > kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016
21 août 2004 à 21:59
:-)

Kilian, débutant en tâche de fond.....
0