[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
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
A voir également:
- Pointeur et chaine de caractère en c
- Caractère ascii - Guide
- Caractere speciaux - Guide
- Caractère spéciaux - Guide
- Chaine tnt gratuite sur mobile - Guide
- Plus de chaine tv - Guide
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."
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."
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
*(pointeur) pour moi c'est la valeur pointé qui doit être égale à un pointeur NULL
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*/
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*/
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
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 :
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...
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...
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.
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.
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
22 août 2004 à 10:00
Si ça peut aider, mon tapis de souris est rouge.
BOOM !
Laissez se propager l'onde de choc...
BOOM !
Laissez se propager l'onde de choc...
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
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
La pensée ne commence qu'avec le doute.
ROGER MARTIN DU GARD
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 !
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 !
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 !
#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 !
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. ;-)
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. ;-)
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.
PS: pas taper merci.
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
22 août 2004 à 14:31
Salut
Ne jamais utiliser gets(); mais plutot fgets();.
extrait du man de linux.
Pour le probleme
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; }
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 );
}
}
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 );
}
}
J'oubliais :
Remarque très importante :
Ecrire '\n' et '\r' et non '/n', '/r'.
Ca marchera mieux... ;)
Take care !
Remarque très importante :
Ecrire '\n' et '\r' et non '/n', '/r'.
Ca marchera mieux... ;)
Take care !
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
23 août 2004 à 00:35
Oups petite erreur :)
Au temps pour moi, gets n'élimine pas les espaces non plus...
Faut les filtrer si on ne les veut pas.
Faut les filtrer si on ne les veut pas.
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
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...
BOOM !
Laissez se propager l'onde de choc...
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
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
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
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
7 nov. 2007 à 19:03
Salut !
Crée ton propre topic, celui ci semble être terminé (il date de Août donc bon... ;D !)
Crée ton propre topic, celui ci semble être terminé (il date de Août donc bon... ;D !)
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
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...
BOOM !
Laissez se propager l'onde de choc...
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
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...
BOOM !
Laissez se propager l'onde de choc...
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
21 août 2004 à 21:45
On est sensés rappliquer au garde à vous??? :-|
Kilian, débutant en tâche de fond.....
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
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. ;-)
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
21 août 2004 à 21:59
:-)
Kilian, débutant en tâche de fond.....