Bonjour,
dans le formatage d'une chaîne de caractère en utilisant une fonction à
liste d'arguments variable, je me demande s'il est possible de trouver la
taille resultante de la chaine de caractère avant, bien évidemment, de la
formater...
inline char *Parse(unsigned int _OutputSize, const char *_ToParse, ...) //
Je voudrais me débarrasser de _OutputSize.
{
if(!_ToParse)
return NULL;
char *Str=malloc(_OutputSize+1); // Dans les exemples existants,
"_OutputSize" est souvent une constante.
if(!Str)
;
va_list ArgPtr;
va_start(ArgPtr, _ToParse);
vsprintf(Str, _ToParse, ArgPtr);
va_end(ArgPtr);
Str[_OutputSize]='\0';
return Str;
}
Sinon question :
si je fais
void *NextArg=_ToParse;
NextArg=NextArg+1; // Là, je met bien la main sur le premier argument
facultatif suivant ?
NextArg=NextArg+1; // Et là, je passe bien au suivant ?
J'ai juste ?
Quelle que soit la plate-forme, ceci est toujours valable ?
Merci de vos lumières.
--
Frédéri MIAILLE
fr.comp.lang.c
fr.comp.lang.c++
fr.comp.os.ms-windows.programmation
fr.comp.graphisme.programmation
pour trouver sa valeur, une méthode (en C99) est : _OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
Oh merci, t'es génial !
Attention, bien tester que l'on est en C99 parce qu'il y a des vsnprintf pre-C99
qui n'ont pas ce joli comportement... Désolé pour le HS mais :
_OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1; n'existe pas sous ma plate-forme. Et à la place je tente d'utiliser _OutputSize = _vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1; qui me plante avec l'assert !=NULL sur le premier paramètre. Avec une chaine allouée de 1 caractère, il me renvoie -1. Comment faire ? ([HS]Je suis sous Windows[/HS]).
"Laurent Deniau" <Laurent.Deniau@cern.ch> a écrit dans le message de
news:3FA90F7E.7090002@cern.ch...
Frédéri MIAILLE wrote:
pour trouver sa valeur, une méthode (en C99) est :
_OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
Oh merci, t'es génial !
Attention, bien tester que l'on est en C99 parce qu'il y a des vsnprintf
pre-C99
qui n'ont pas ce joli comportement...
Désolé pour le HS mais :
_OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
n'existe pas sous ma plate-forme.
Et à la place je tente d'utiliser
_OutputSize = _vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
qui me plante avec l'assert !=NULL sur le premier paramètre.
Avec une chaine allouée de 1 caractère, il me renvoie -1.
Comment faire ? ([HS]Je suis sous Windows[/HS]).
pour trouver sa valeur, une méthode (en C99) est : _OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
Oh merci, t'es génial !
Attention, bien tester que l'on est en C99 parce qu'il y a des vsnprintf pre-C99
qui n'ont pas ce joli comportement... Désolé pour le HS mais :
_OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1; n'existe pas sous ma plate-forme. Et à la place je tente d'utiliser _OutputSize = _vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1; qui me plante avec l'assert !=NULL sur le premier paramètre. Avec une chaine allouée de 1 caractère, il me renvoie -1. Comment faire ? ([HS]Je suis sous Windows[/HS]).
pour trouver sa valeur, une méthode (en C99) est : _OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
Oh merci, t'es génial !
Attention, bien tester que l'on est en C99 parce qu'il y a des vsnprintf
pre-C99
qui n'ont pas ce joli comportement...
Désolé pour le HS mais : _OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1; n'existe pas sous ma plate-forme. Et à la place je tente d'utiliser _OutputSize = _vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1; qui me plante avec l'assert !=NULL sur le premier paramètre. Avec une chaine allouée de 1 caractère, il me renvoie -1. Comment faire ? ([HS]Je suis sous Windows[/HS]).
C'est justement ce que je voulais souligner, certains vsnprintf pre-C99 renvoient -1 en cas de taille buffer insuffisante.
Il faut proceder par iteration en doublant la taille du buffer tant que vsnprintf renvoie -1 et eventuellement reajuster la taille a la fin.
Sinon utilise vfprintf (C90) sur le 'null device' de ton OS (/dev/null sous Unix) ou sur un fichier temporaire (cf tmpfile, c'est C90) pour obtenir la taille du buffer.
a+, ld.
-- [ Laurent Deniau -- Scientific Computing & Data Analysis ] [ CERN -- European Center for Nuclear Research ] [ - http://cern.ch/Laurent.Deniau ] [ -- One becomes old when dreams become regrets -- ]
Frédéri MIAILLE wrote:
"Laurent Deniau" <Laurent.Deniau@cern.ch> a écrit dans le message de
news:3FA90F7E.7090002@cern.ch...
Frédéri MIAILLE wrote:
pour trouver sa valeur, une méthode (en C99) est :
_OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
Oh merci, t'es génial !
Attention, bien tester que l'on est en C99 parce qu'il y a des vsnprintf
pre-C99
qui n'ont pas ce joli comportement...
Désolé pour le HS mais :
_OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
n'existe pas sous ma plate-forme.
Et à la place je tente d'utiliser
_OutputSize = _vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
qui me plante avec l'assert !=NULL sur le premier paramètre.
Avec une chaine allouée de 1 caractère, il me renvoie -1.
Comment faire ? ([HS]Je suis sous Windows[/HS]).
C'est justement ce que je voulais souligner, certains vsnprintf pre-C99
renvoient -1 en cas de taille buffer insuffisante.
Il faut proceder par iteration en doublant la taille du buffer tant que
vsnprintf renvoie -1 et eventuellement reajuster la taille a la fin.
Sinon utilise vfprintf (C90) sur le 'null device' de ton OS (/dev/null sous
Unix) ou sur un fichier temporaire (cf tmpfile, c'est C90) pour obtenir la
taille du buffer.
a+, ld.
--
[ Laurent Deniau -- Scientific Computing & Data Analysis ]
[ CERN -- European Center for Nuclear Research ]
[ Laurent.Deniau@cern.ch - http://cern.ch/Laurent.Deniau ]
[ -- One becomes old when dreams become regrets -- ]
pour trouver sa valeur, une méthode (en C99) est : _OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1;
Oh merci, t'es génial !
Attention, bien tester que l'on est en C99 parce qu'il y a des vsnprintf
pre-C99
qui n'ont pas ce joli comportement...
Désolé pour le HS mais : _OutputSize = vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1; n'existe pas sous ma plate-forme. Et à la place je tente d'utiliser _OutputSize = _vsnprintf (NULL, 0, _ToParse, ArgPtr) + 1; qui me plante avec l'assert !=NULL sur le premier paramètre. Avec une chaine allouée de 1 caractère, il me renvoie -1. Comment faire ? ([HS]Je suis sous Windows[/HS]).
C'est justement ce que je voulais souligner, certains vsnprintf pre-C99 renvoient -1 en cas de taille buffer insuffisante.
Il faut proceder par iteration en doublant la taille du buffer tant que vsnprintf renvoie -1 et eventuellement reajuster la taille a la fin.
Sinon utilise vfprintf (C90) sur le 'null device' de ton OS (/dev/null sous Unix) ou sur un fichier temporaire (cf tmpfile, c'est C90) pour obtenir la taille du buffer.
a+, ld.
-- [ Laurent Deniau -- Scientific Computing & Data Analysis ] [ CERN -- European Center for Nuclear Research ] [ - http://cern.ch/Laurent.Deniau ] [ -- One becomes old when dreams become regrets -- ]
Frédéri MIAILLE
Ok bon merci. Je définis une constante pour la taille de la chaine et puis voilà. Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf renvoie -1) auquel cas l'utilisateur changera la taille du buffer. C'est plus simple et certainement plus rapide que boucler sur le _vsnprintf jusqu'à ce qu'il renvoie une taille valide.
Ok bon merci.
Je définis une constante pour la taille de la chaine et puis voilà.
Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf
renvoie -1) auquel cas l'utilisateur changera la taille du buffer.
C'est plus simple et certainement plus rapide que boucler sur le _vsnprintf
jusqu'à ce qu'il renvoie une taille valide.
Ok bon merci. Je définis une constante pour la taille de la chaine et puis voilà. Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf renvoie -1) auquel cas l'utilisateur changera la taille du buffer. C'est plus simple et certainement plus rapide que boucler sur le _vsnprintf jusqu'à ce qu'il renvoie une taille valide.
Ok bon merci. Je définis une constante pour la taille de la chaine et puis voilà. Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf renvoie -1) auquel cas l'utilisateur changera la taille du buffer. C'est plus simple et certainement plus rapide que boucler sur le _vsnpr intf jusqu'à ce qu'il renvoie une taille valide.
Merci beaucoup en tout cas.
béh non c'est simple
char *tmp; int res; _OutputSize = 2; _ToParse = NULL; do { tmp = realloc (Str, _OutputSize); if (tmp == NULL) {free (Str); return NULL;} Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */ if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */ if (res >= _OutputSize) _OutputSize = res + 1;
} while (res >= 0 && res < _OutputSize);
Frédéri MIAILLE a écrit:
Ok bon merci.
Je définis une constante pour la taille de la chaine et puis voilà.
Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf
renvoie -1) auquel cas l'utilisateur changera la taille du buffer.
C'est plus simple et certainement plus rapide que boucler sur le _vsnpr intf
jusqu'à ce qu'il renvoie une taille valide.
Merci beaucoup en tout cas.
béh non c'est simple
char *tmp;
int res;
_OutputSize = 2;
_ToParse = NULL;
do {
tmp = realloc (Str, _OutputSize);
if (tmp == NULL) {free (Str); return NULL;}
Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */
if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */
if (res >= _OutputSize) _OutputSize = res + 1;
Ok bon merci. Je définis une constante pour la taille de la chaine et puis voilà. Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf renvoie -1) auquel cas l'utilisateur changera la taille du buffer. C'est plus simple et certainement plus rapide que boucler sur le _vsnpr intf jusqu'à ce qu'il renvoie une taille valide.
Merci beaucoup en tout cas.
béh non c'est simple
char *tmp; int res; _OutputSize = 2; _ToParse = NULL; do { tmp = realloc (Str, _OutputSize); if (tmp == NULL) {free (Str); return NULL;} Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */ if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */ if (res >= _OutputSize) _OutputSize = res + 1;
} while (res >= 0 && res < _OutputSize);
Al 1
Frédéri MIAILLE a écrit:
Ok bon merci. Je définis une constante pour la taille de la chaine et puis voilà . Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf renvoie -1) auquel cas l'utilisateur changera la taille du buffer. C'est plus simple et certainement plus rapide que boucler sur le _vsnprintf
jusqu'à ce qu'il renvoie une taille valide.
Merci beaucoup en tout cas.
béh non c'est simple
char *tmp; int res; _OutputSize = 2; _ToParse = NULL; do { tmp = realloc (Str, _OutputSize); if (tmp == NULL) {free (Str); return NULL;} Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */ if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */ if (res >= _OutputSize) _OutputSize = res + 1;
} while (res == -1 || res >= _OutputSize);
Frédéri MIAILLE a écrit:
Ok bon merci.
Je définis une constante pour la taille de la chaine et puis voilà .
Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf
renvoie -1) auquel cas l'utilisateur changera la taille du buffer.
C'est plus simple et certainement plus rapide que boucler sur le
_vsnprintf
jusqu'à ce qu'il renvoie une taille valide.
Merci beaucoup en tout cas.
béh non c'est simple
char *tmp;
int res;
_OutputSize = 2;
_ToParse = NULL;
do {
tmp = realloc (Str, _OutputSize);
if (tmp == NULL) {free (Str); return NULL;}
Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */
if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */
if (res >= _OutputSize) _OutputSize = res + 1;
Ok bon merci. Je définis une constante pour la taille de la chaine et puis voilà . Je contrôle s'il y à erreur au niveau de la taille (si _vsnprintf renvoie -1) auquel cas l'utilisateur changera la taille du buffer. C'est plus simple et certainement plus rapide que boucler sur le _vsnprintf
jusqu'à ce qu'il renvoie une taille valide.
Merci beaucoup en tout cas.
béh non c'est simple
char *tmp; int res; _OutputSize = 2; _ToParse = NULL; do { tmp = realloc (Str, _OutputSize); if (tmp == NULL) {free (Str); return NULL;} Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */ if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */ if (res >= _OutputSize) _OutputSize = res + 1;
} while (res == -1 || res >= _OutputSize);
Frédéri MIAILLE
béh non c'est simple
char *tmp; int res; _OutputSize = 2; _ToParse = NULL; do { tmp = realloc (Str, _OutputSize); if (tmp == NULL) {free (Str); return NULL;} Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */ if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */ if (res >= _OutputSize) _OutputSize = res + 1;
} while (res == -1 || res >= _OutputSize);
Merci infiniment mais "while (res == -1 || res >= _OutputSize);" me gêne pour une simple copie. C'est long pour moi surtout que ma chaîne peut gonfler de 1 octet à 1 méga-octet. Aussi : "_OutputSize *= 2;" me gêne un peu (bien que fonctionnel) car pour 1 octet manquant je peux avoir 999Ko de supplément non utilisés. Je préfère emmerder le programmeur mais je préfère privilégier les microsecondes. Pour la petite histoire, j'ai besoin de faire appel à cette fonction dans la boucle principale et elle sera appelée en permanence. D'ou le "HIC". Dans le cas d'un code normé C90 (on dit comme ça ? je me trompe ?), ça aurait été super (mais je le garde pour ma version Linux donc le fil de discussion m'a été fort utile). Oui, la programmation, c'est comme les femmes, quand on a un problème au niveau de la norme on est obligé de s'emmerder avec des détails.
char *tmp;
int res;
_OutputSize = 2;
_ToParse = NULL;
do {
tmp = realloc (Str, _OutputSize);
if (tmp == NULL) {free (Str); return NULL;}
Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */
if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */
if (res >= _OutputSize) _OutputSize = res + 1;
} while (res == -1 || res >= _OutputSize);
Merci infiniment mais
"while (res == -1 || res >= _OutputSize);" me gêne pour une simple copie.
C'est long pour moi surtout que ma chaîne peut gonfler de 1 octet à 1
méga-octet.
Aussi :
"_OutputSize *= 2;"
me gêne un peu (bien que fonctionnel) car pour 1 octet manquant je peux
avoir 999Ko de supplément non utilisés.
Je préfère emmerder le programmeur mais je préfère privilégier les
microsecondes.
Pour la petite histoire, j'ai besoin de faire appel à cette fonction dans la
boucle principale et elle sera appelée en permanence.
D'ou le "HIC".
Dans le cas d'un code normé C90 (on dit comme ça ? je me trompe ?), ça
aurait été super (mais je le garde pour ma version Linux donc le fil de
discussion m'a été fort utile).
Oui, la programmation, c'est comme les femmes, quand on a un problème au
niveau de la norme on est obligé de s'emmerder avec des détails.
char *tmp; int res; _OutputSize = 2; _ToParse = NULL; do { tmp = realloc (Str, _OutputSize); if (tmp == NULL) {free (Str); return NULL;} Str = tmp;
res = vsnprintf (Str, _ToParse, ArgPtr);
/* Cas du renvoi de -1 si c'est trop grand */ if (res == -1) _OutputSize *= 2;
/* Cas C99-compliant */ if (res >= _OutputSize) _OutputSize = res + 1;
} while (res == -1 || res >= _OutputSize);
Merci infiniment mais "while (res == -1 || res >= _OutputSize);" me gêne pour une simple copie. C'est long pour moi surtout que ma chaîne peut gonfler de 1 octet à 1 méga-octet. Aussi : "_OutputSize *= 2;" me gêne un peu (bien que fonctionnel) car pour 1 octet manquant je peux avoir 999Ko de supplément non utilisés. Je préfère emmerder le programmeur mais je préfère privilégier les microsecondes. Pour la petite histoire, j'ai besoin de faire appel à cette fonction dans la boucle principale et elle sera appelée en permanence. D'ou le "HIC". Dans le cas d'un code normé C90 (on dit comme ça ? je me trompe ?), ça aurait été super (mais je le garde pour ma version Linux donc le fil de discussion m'a été fort utile). Oui, la programmation, c'est comme les femmes, quand on a un problème au niveau de la norme on est obligé de s'emmerder avec des détails.