Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

C++ et sscanf

11 réponses
Avatar
david
Bonjour,
J'ai un segfault a l'execution avec sscanf en C++


const char * test;

if (strstr(line,"WebEnv") != NULL)
{
sscanf(line,"Element: WebEnv Value : %s", test);
std::cout << "Webenv" << test << std::endl;

}

Voici le fichier que j'essaye de parser:

Element: WebEnv Value :
0miNudVD0EoeIMYkUNvkgG76q1_Ncviqf4Zmc4y7MllUnaMRI-eT

Est ce que quelqu'un a une idee ??

10 réponses

1 2
Avatar
Andre Heinen
sscanf va lire une information dans line, et la recopie dans
test. Par conséquent:

1) test ne peut pas être const, puisque tu as l'intention de la
modifier,

2) tu dois écrire sscanf(... &test). Avec &. Pour donner à
sscanf l'_adresse_ de test.

Ce ne serait pas arrivé si tu avais utilisé un stringstream. Si
tu continues à utiliser les fonctions de style C, tu auras
d'autres ennuis de ce genre.

--
Andre Heinen
My address is "a dot heinen at europeanlink dot com"
Avatar
david
C'est quoi les stringstream ?

Andre Heinen wrote:
sscanf va lire une information dans line, et la recopie dans
test. Par conséquent:

1) test ne peut pas être const, puisque tu as l'intention de la
modifier,

2) tu dois écrire sscanf(... &test). Avec &. Pour donner à
sscanf l'_adresse_ de test.

Ce ne serait pas arrivé si tu avais utilisé un stringstream. Si
tu continues à utiliser les fonctions de style C, tu auras
d'autres ennuis de ce genre.



Avatar
Rémy
"Andre Heinen" a écrit dans le message de
news:

2) tu dois écrire sscanf(... &test). Avec &. Pour donner à
sscanf l'_adresse_ de test.



Non puisque test est un char *.

Par contre, il faut lui allouer de la mémoire avec new ou malloc.

Ou alors déclarer test comme char test[ma_taille] et utiliser &test comme le
dit andré.


Ce ne serait pas arrivé si tu avais utilisé un stringstream. Si
tu continues à utiliser les fonctions de style C, tu auras
d'autres ennuis de ce genre.



Tout à fait d'accord.

--
Andre Heinen


Avatar
Andre Heinen
On Fri, 05 Mar 2004 13:55:50 +0100, david wrote:

C'est quoi les stringstream ?


Je suppose que tu connais cin et cout. En gros:

int i;

Console:
C: scanf("%d", &i);
printf("%d", i);
C++: cin >> i;
cout << i;

Fichiers:
C: FILE* f;
fscanf(f, "%d", &i);
fprintf(f, "%d", i);
C++: fstream f;
f >> i;
f << i;

Chaînes de caractères:
C: char cc[100];
sscanf(cc, "%d", &i);
sprintf(cc, "%d", i);
C++: stringstream ss;
ss >> i;
ss << i;

La méthode C++ t'évitera beaucoup d'ennuis car:
- pas de risque d'oublier le &,
- pas besoin de spécifier le format ("%d") et donc pas de risque
de se tromper à ce niveau,
- pas besoin de spécifier la taille de cc, et donc pas de risque
de buffer overflow.

De plus, c'est plus clair, et ça facilite la programmation
générique.

Bon week-end,

--
Andre Heinen
My address is "a dot heinen at europeanlink dot com"

Avatar
david
Finalement j'ai utilisé la stringstream que je trouve trés souple, merci
pour les conseils...


std::ostringstream ost;
char *colon;

while (lire chaque ligne de mon fichier)
{
std::istringstream ist(ligne);
if (strstr(ligne,"WebEnv") != NULL)
{
ist >> element >> colon >> webenv;
ost << "Valeur" << webenv;
}
}

et puis cout <<ost.str()<<endl

Mon fichier de départ etait comme ca:
WebEnv : 00nwg-B5D6PnY10k00TSWj-BFGTaeglUnAzVtCRTmdA-znYqBdjk



Andre Heinen wrote:
On Fri, 05 Mar 2004 13:55:50 +0100, david wrote:


C'est quoi les stringstream ?



Je suppose que tu connais cin et cout. En gros:

int i;

Console:
C: scanf("%d", &i);
printf("%d", i);
C++: cin >> i;
cout << i;

Fichiers:
C: FILE* f;
fscanf(f, "%d", &i);
fprintf(f, "%d", i);
C++: fstream f;
f >> i;
f << i;

Chaînes de caractères:
C: char cc[100];
sscanf(cc, "%d", &i);
sprintf(cc, "%d", i);
C++: stringstream ss;
ss >> i;
ss << i;

La méthode C++ t'évitera beaucoup d'ennuis car:
- pas de risque d'oublier le &,
- pas besoin de spécifier le format ("%d") et donc pas de risque
de se tromper à ce niveau,
- pas besoin de spécifier la taille de cc, et donc pas de risque
de buffer overflow.

De plus, c'est plus clair, et ça facilite la programmation
générique.

Bon week-end,




Avatar
Andre Heinen
On Fri, 5 Mar 2004 15:10:31 +0100, "Rémy"
wrote:


"Andre Heinen" a écrit dans le message de
news:

2) tu dois écrire sscanf(... &test). Avec &. Pour donner à
sscanf l'_adresse_ de test.



Non puisque test est un char *.


Effectivement. Au temps pour moi.

Par contre, il faut lui allouer de la mémoire avec new ou malloc.
Ou alors déclarer test comme char test[ma_taille] et utiliser &test comme le
dit andré.



David, comment as-tu initialisé le pointeur?

--
Andre Heinen
My address is "a dot heinen at europeanlink dot com"


Avatar
david
Oui en fait j'avais alloué l'espace au début, c'est pourca que ca me
donner un erreur. Du coup le stringstream est plus simple et on a plus
besoin de s'occuper de louer l'espace

Andre Heinen wrote:
On Fri, 5 Mar 2004 15:10:31 +0100, "Rémy"
wrote:


"Andre Heinen" a écrit dans le message de
news:

2) tu dois écrire sscanf(... &test). Avec &. Pour donner à
sscanf l'_adresse_ de test.



Non puisque test est un char *.



Effectivement. Au temps pour moi.


Par contre, il faut lui allouer de la mémoire avec new ou malloc.
Ou alors déclarer test comme char test[ma_taille] et utiliser &test comme le
dit andré.




David, comment as-tu initialisé le pointeur?





Avatar
Tom
2) tu dois écrire sscanf(... &test). Avec &. Pour donner à
sscanf l'_adresse_ de test.



Non puisque test est un char *.


Il me semblait bien.


Par contre, il faut lui allouer de la mémoire avec new ou malloc.

Ou alors déclarer test comme char test[ma_taille] et utiliser &test comme
le

dit andré.


Il n'y a pas de différence, il faut également utiliser test directement.

Petit rappel de C très basique : un nom de tableau est un pointeur constant
vers la première case du tableau.

Olivier Coanet


Avatar
Michel Michaud
Dans news:c2a3qg$vee$,
Petit rappel de C très basique : un nom de tableau est un pointeur
constant vers la première case du tableau.


Petite correction formelle : un nom de tableau peut être
*converti* implicitement, mais seulement au besoin, vers
l'adresse de la première case du tableau.

int t[10];
int* p= &t[0];
// Ou int* p= t; mais
assert(sizeof(p) != sizeof(t));

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Horst Kraemer
On Fri, 5 Mar 2004 15:10:31 +0100, "Rémy"
wrote:


"Andre Heinen" a écrit dans le message de
news:

2) tu dois écrire sscanf(... &test). Avec &. Pour donner à
sscanf l'_adresse_ de test.



Non puisque test est un char *.

Par contre, il faut lui allouer de la mémoire avec new ou malloc.

Ou alors déclarer test comme char test[ma_taille] et utiliser &test comme le
dit andré.


Toujours faux - même si cela marchera dans la plupart des cas.

&test est un pointeur vers tableau de char. Il faut un pointeur vers
char. Alors simplement 'test' comme si test était un pointeur.

--
Horst


1 2