sscanf(msg, "%[^:]:%s", var1, var2);
Bien sûr il manquait encore un %...
Mais notez bien que la ligne
sscanf(msg, "%[^:]:%[^:]", var1, var2);
ne vérifie aucunement que les parties de msg de part et d'autre du ':'
"tiennent" dans var1 et var2.
Il serait bien préférable de préciser la taille des tableaux var1 et var2 pour
éviter un débordement potentiel qui pourrait créer une faille de sécurité ou un
quelconque autre comportement indéfini.
Malheureusement la syntaxe de sscanf ne
permet pas de préciser la taille des tableaux de char que explicitement dans la
chaine de format, et avec un nombre qui n'est pas sizeof(var1) !
Donc si les tableaux var1 ou var2 changent de taille ou sont d'une taille
variable ou paramétrique, ca devient particulièrement acrobatique puisqu'il faut
fabriquer la chaine de sscanf() avec printf(), ce qui empêche d'ailleurs le
compilateur de faire des vérifications simples de cohérence entre la chaine de
format de sscanf() et les paramètres qui lui sont passés.
La seule solution dans le cas présent consiste à dimensionner var1 et var2 à la
même taille que msg... Mais cette taille n'est pas connue à compile time...
Enfin autre problème : le résultat de sscanf() permet de savoir combien de
champs ont été traités, ou si une erreur s'est produite.
Comme ce résultat n'est pas stocké, on ne peut pas savoir ce qui s'est
réellement passé, et le contenu de var1 et var2 est potentiellement quelconque,
donc même en mesurer la taille avec strlen() peut déclencher un comportement
indéfini.
Conclusion : NE PAS UTILISER SCANF !
sscanf(msg, "%[^:]:%s", var1, var2);
Bien sûr il manquait encore un %...
Mais notez bien que la ligne
sscanf(msg, "%[^:]:%[^:]", var1, var2);
ne vérifie aucunement que les parties de msg de part et d'autre du ':'
"tiennent" dans var1 et var2.
Il serait bien préférable de préciser la taille des tableaux var1 et var2 pour
éviter un débordement potentiel qui pourrait créer une faille de sécurité ou un
quelconque autre comportement indéfini.
Malheureusement la syntaxe de sscanf ne
permet pas de préciser la taille des tableaux de char que explicitement dans la
chaine de format, et avec un nombre qui n'est pas sizeof(var1) !
Donc si les tableaux var1 ou var2 changent de taille ou sont d'une taille
variable ou paramétrique, ca devient particulièrement acrobatique puisqu'il faut
fabriquer la chaine de sscanf() avec printf(), ce qui empêche d'ailleurs le
compilateur de faire des vérifications simples de cohérence entre la chaine de
format de sscanf() et les paramètres qui lui sont passés.
La seule solution dans le cas présent consiste à dimensionner var1 et var2 à la
même taille que msg... Mais cette taille n'est pas connue à compile time...
Enfin autre problème : le résultat de sscanf() permet de savoir combien de
champs ont été traités, ou si une erreur s'est produite.
Comme ce résultat n'est pas stocké, on ne peut pas savoir ce qui s'est
réellement passé, et le contenu de var1 et var2 est potentiellement quelconque,
donc même en mesurer la taille avec strlen() peut déclencher un comportement
indéfini.
Conclusion : NE PAS UTILISER SCANF !
sscanf(msg, "%[^:]:%s", var1, var2);
Bien sûr il manquait encore un %...
Mais notez bien que la ligne
sscanf(msg, "%[^:]:%[^:]", var1, var2);
ne vérifie aucunement que les parties de msg de part et d'autre du ':'
"tiennent" dans var1 et var2.
Il serait bien préférable de préciser la taille des tableaux var1 et var2 pour
éviter un débordement potentiel qui pourrait créer une faille de sécurité ou un
quelconque autre comportement indéfini.
Malheureusement la syntaxe de sscanf ne
permet pas de préciser la taille des tableaux de char que explicitement dans la
chaine de format, et avec un nombre qui n'est pas sizeof(var1) !
Donc si les tableaux var1 ou var2 changent de taille ou sont d'une taille
variable ou paramétrique, ca devient particulièrement acrobatique puisqu'il faut
fabriquer la chaine de sscanf() avec printf(), ce qui empêche d'ailleurs le
compilateur de faire des vérifications simples de cohérence entre la chaine de
format de sscanf() et les paramètres qui lui sont passés.
La seule solution dans le cas présent consiste à dimensionner var1 et var2 à la
même taille que msg... Mais cette taille n'est pas connue à compile time...
Enfin autre problème : le résultat de sscanf() permet de savoir combien de
champs ont été traités, ou si une erreur s'est produite.
Comme ce résultat n'est pas stocké, on ne peut pas savoir ce qui s'est
réellement passé, et le contenu de var1 et var2 est potentiellement quelconque,
donc même en mesurer la taille avec strlen() peut déclencher un comportement
indéfini.
Conclusion : NE PAS UTILISER SCANF !
Charlie Gordon wrote:Conclusion : NE PAS UTILISER SCANF !
Il est où le problème avec scanf ? ;-) Dans ce qui suit, quelle est
la différence avec fgets() d'un point de vue pratique par exemple ?
#include <stdio.h>
#define LG_SAISIE_STDIN 20
#define STR_(s) #s
#define STR(s) STR_(s)
int main(void)
{
int rc;
char tamponSaisie[LG_SAISIE_STDIN+1] = { ' ' };
rc = scanf("%"STR(LG_SAISIE_STDIN)"[^n]%*[^n]",tamponSaisie);
getchar();
if (rc != EOF) {
printf("Donnees saisies : n%sn", tamponSaisie);
}
else {
puts("Erreur lors de la saisie");
}
return 0;
}
Charlie Gordon wrote:
Conclusion : NE PAS UTILISER SCANF !
Il est où le problème avec scanf ? ;-) Dans ce qui suit, quelle est
la différence avec fgets() d'un point de vue pratique par exemple ?
#include <stdio.h>
#define LG_SAISIE_STDIN 20
#define STR_(s) #s
#define STR(s) STR_(s)
int main(void)
{
int rc;
char tamponSaisie[LG_SAISIE_STDIN+1] = { ' ' };
rc = scanf("%"STR(LG_SAISIE_STDIN)"[^n]%*[^n]",tamponSaisie);
getchar();
if (rc != EOF) {
printf("Donnees saisies : n%sn", tamponSaisie);
}
else {
puts("Erreur lors de la saisie");
}
return 0;
}
Charlie Gordon wrote:Conclusion : NE PAS UTILISER SCANF !
Il est où le problème avec scanf ? ;-) Dans ce qui suit, quelle est
la différence avec fgets() d'un point de vue pratique par exemple ?
#include <stdio.h>
#define LG_SAISIE_STDIN 20
#define STR_(s) #s
#define STR(s) STR_(s)
int main(void)
{
int rc;
char tamponSaisie[LG_SAISIE_STDIN+1] = { ' ' };
rc = scanf("%"STR(LG_SAISIE_STDIN)"[^n]%*[^n]",tamponSaisie);
getchar();
if (rc != EOF) {
printf("Donnees saisies : n%sn", tamponSaisie);
}
else {
puts("Erreur lors de la saisie");
}
return 0;
}
Charlie Gordon écrivit dans news:d4nkco$ma3$Mais notez bien que la ligne
sscanf(msg, "%[^:]:%[^:]", var1, var2);
Attention aux n qui traînent en «fin» de msg: ils auraient été un butoir
pour %s, mais %[^n] va passer outre, ce qui peut être un souci.ne vérifie aucunement que les parties de msg de part et d'autre du ':'
"tiennent" dans var1 et var2.
Il serait bien préférable de préciser la taille des tableaux var1 et var2
pouréviter un débordement potentiel qui pourrait créer une faille de sécurité
ou unquelconque autre comportement indéfini.
Pas sûr.
Le contrôle de taille se fait avant, au niveau de l'acquisition de msg. Si
tu as dimensionné var1 et var2 de la même taille que msg, je ne vois pas
comment tu peux avoir un débordement, sauf en présence de bogue dans
l'implémentation de sscanf.
Maintenant, si tu es obligé (par circonstance extérieure) d'avoir une taille
donnée pour var1 ou var2 (inférieure à celle de msg), il faut effectivement
imposer des limites:
#define ch(x) cx(x) /* truc horrible pour convertir la valeur */
#define cx(x) #x /* d'une constante en morceau de chaîne */
char var1[TAILLE_DE_VAR1], var2[TAILLE_DE_VAR2];
if( 2 != sscanf(msg, "%" ch(TAILLE_DE_VAR1) "[^:]:"
"%" ch(TAILLE_DE_VAR2) "[^:]",
var1, var2) ) /*...*/
ce qui renforce les raisons de vérifier la valeur retournée (à quoi sert de
poser des limites si elles ne sont pas vérifiées ?)
Conclusion : NE PAS UTILISER SCANF !
Dommage. ;-)
Antoine (qui se *précipite* sur strtok() pour faire ce genre de découpage
:-)) )
Charlie Gordon écrivit dans news:d4nkco$ma3$1@reader1.imaginet.fr...
Mais notez bien que la ligne
sscanf(msg, "%[^:]:%[^:]", var1, var2);
Attention aux n qui traînent en «fin» de msg: ils auraient été un butoir
pour %s, mais %[^n] va passer outre, ce qui peut être un souci.
ne vérifie aucunement que les parties de msg de part et d'autre du ':'
"tiennent" dans var1 et var2.
Il serait bien préférable de préciser la taille des tableaux var1 et var2
pour
éviter un débordement potentiel qui pourrait créer une faille de sécurité
ou un
quelconque autre comportement indéfini.
Pas sûr.
Le contrôle de taille se fait avant, au niveau de l'acquisition de msg. Si
tu as dimensionné var1 et var2 de la même taille que msg, je ne vois pas
comment tu peux avoir un débordement, sauf en présence de bogue dans
l'implémentation de sscanf.
Maintenant, si tu es obligé (par circonstance extérieure) d'avoir une taille
donnée pour var1 ou var2 (inférieure à celle de msg), il faut effectivement
imposer des limites:
#define ch(x) cx(x) /* truc horrible pour convertir la valeur */
#define cx(x) #x /* d'une constante en morceau de chaîne */
char var1[TAILLE_DE_VAR1], var2[TAILLE_DE_VAR2];
if( 2 != sscanf(msg, "%" ch(TAILLE_DE_VAR1) "[^:]:"
"%" ch(TAILLE_DE_VAR2) "[^:]",
var1, var2) ) /*...*/
ce qui renforce les raisons de vérifier la valeur retournée (à quoi sert de
poser des limites si elles ne sont pas vérifiées ?)
Conclusion : NE PAS UTILISER SCANF !
Dommage. ;-)
Antoine (qui se *précipite* sur strtok() pour faire ce genre de découpage
:-)) )
Charlie Gordon écrivit dans news:d4nkco$ma3$Mais notez bien que la ligne
sscanf(msg, "%[^:]:%[^:]", var1, var2);
Attention aux n qui traînent en «fin» de msg: ils auraient été un butoir
pour %s, mais %[^n] va passer outre, ce qui peut être un souci.ne vérifie aucunement que les parties de msg de part et d'autre du ':'
"tiennent" dans var1 et var2.
Il serait bien préférable de préciser la taille des tableaux var1 et var2
pouréviter un débordement potentiel qui pourrait créer une faille de sécurité
ou unquelconque autre comportement indéfini.
Pas sûr.
Le contrôle de taille se fait avant, au niveau de l'acquisition de msg. Si
tu as dimensionné var1 et var2 de la même taille que msg, je ne vois pas
comment tu peux avoir un débordement, sauf en présence de bogue dans
l'implémentation de sscanf.
Maintenant, si tu es obligé (par circonstance extérieure) d'avoir une taille
donnée pour var1 ou var2 (inférieure à celle de msg), il faut effectivement
imposer des limites:
#define ch(x) cx(x) /* truc horrible pour convertir la valeur */
#define cx(x) #x /* d'une constante en morceau de chaîne */
char var1[TAILLE_DE_VAR1], var2[TAILLE_DE_VAR2];
if( 2 != sscanf(msg, "%" ch(TAILLE_DE_VAR1) "[^:]:"
"%" ch(TAILLE_DE_VAR2) "[^:]",
var1, var2) ) /*...*/
ce qui renforce les raisons de vérifier la valeur retournée (à quoi sert de
poser des limites si elles ne sont pas vérifiées ?)
Conclusion : NE PAS UTILISER SCANF !
Dommage. ;-)
Antoine (qui se *précipite* sur strtok() pour faire ce genre de découpage
:-)) )
Conclusion : NE PAS UTILISER SCANF !
AMHA, pour traiter les chaines de caractères, ne pas utiliser le langage
C est une réponse encore meilleure. Mais on a peut-être pas le choix.
Conclusion : NE PAS UTILISER SCANF !
AMHA, pour traiter les chaines de caractères, ne pas utiliser le langage
C est une réponse encore meilleure. Mais on a peut-être pas le choix.
Conclusion : NE PAS UTILISER SCANF !
AMHA, pour traiter les chaines de caractères, ne pas utiliser le langage
C est une réponse encore meilleure. Mais on a peut-être pas le choix.
C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Il est où le problème avec scanf ? ;-) Dans ce qui suit, quelle est
la différence avec fgets() d'un point de vue pratique par exemple ?
Il est où le problème avec scanf ? ;-) Dans ce qui suit, quelle est
la différence avec fgets() d'un point de vue pratique par exemple ?
Il est où le problème avec scanf ? ;-) Dans ce qui suit, quelle est
la différence avec fgets() d'un point de vue pratique par exemple ?
Charlie Gordon wrote:C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
Charlie Gordon wrote:
C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
Charlie Gordon wrote:C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
OK pour les remarques qui n'étaient pas directement à ton attention, et sans
doute pas dans le bon ordre, mais même si on a pas le choix du langage et
qu'on doive traiter des chaines de caractères en C (*) scanf() est une
mauvaise solution, tout comme strtok(), strncpy, strncat() et d'autres.
OK pour les remarques qui n'étaient pas directement à ton attention, et sans
doute pas dans le bon ordre, mais même si on a pas le choix du langage et
qu'on doive traiter des chaines de caractères en C (*) scanf() est une
mauvaise solution, tout comme strtok(), strncpy, strncat() et d'autres.
OK pour les remarques qui n'étaient pas directement à ton attention, et sans
doute pas dans le bon ordre, mais même si on a pas le choix du langage et
qu'on doive traiter des chaines de caractères en C (*) scanf() est une
mauvaise solution, tout comme strtok(), strncpy, strncat() et d'autres.
Charlie Gordon wrote:C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
Charlie Gordon wrote:
C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
Charlie Gordon wrote:C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
Harpo wrote on 27/04/05 :Charlie Gordon wrote:C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
- strncpy() ne met pas le 0 final quand il sature (chaine mal formée)
- strncat() est bien, à condition d'être bien révéillé. (la chaine de
destination doit être initialisée..., ne pas se tromper dans les
tailles passées en paramètre, laisser une place pour le 0 etc.). Je
m'en sert tout le temps pour faire des extractions en une ligne, ça me
va.
Harpo wrote on 27/04/05 :
Charlie Gordon wrote:
C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
- strncpy() ne met pas le 0 final quand il sature (chaine mal formée)
- strncat() est bien, à condition d'être bien révéillé. (la chaine de
destination doit être initialisée..., ne pas se tromper dans les
tailles passées en paramètre, laisser une place pour le 0 etc.). Je
m'en sert tout le temps pour faire des extractions en une ligne, ça me
va.
Harpo wrote on 27/04/05 :Charlie Gordon wrote:C'est trop merdique, utiliser les fonctions strxxx.
Sauf bien sûr strncpy, strncat et strtok qui ont leur propre lot de
problèmes merdiques.
Pour strtok, je savais, elle est quand même limite utilisable quand on
sait ce qu'on fait, pour strncpy et strncat, je ne vois pas ce que vous
leur reprochez.
- strncpy() ne met pas le 0 final quand il sature (chaine mal formée)
- strncat() est bien, à condition d'être bien révéillé. (la chaine de
destination doit être initialisée..., ne pas se tromper dans les
tailles passées en paramètre, laisser une place pour le 0 etc.). Je
m'en sert tout le temps pour faire des extractions en une ligne, ça me
va.