Fonctions à paramètres infinis
Fermé
Lap-top
Messages postés
56
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
5 octobre 2016
-
Modifié par Whismeril le 31/01/2015 à 15:39
Lap-top Messages postés 56 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 5 octobre 2016 - 6 févr. 2015 à 21:40
Lap-top Messages postés 56 Date d'inscription vendredi 9 décembre 2011 Statut Membre Dernière intervention 5 octobre 2016 - 6 févr. 2015 à 21:40
A voir également:
- Fonctions à paramètres infinis
- Paramètres s'arrête systématiquement - Forum Samsung
- Windows update un problème s'est produit. essayez d'ouvrir paramètres plus tard ✓ - Forum Windows
- Le bon coin mon compte parametres - Guide
- Codes secrets Android : accéder aux fonctions cachées - Guide
- L'Application s'arrête systématiquement sur Android ✓ - Forum Tablette tactile
3 réponses
ElementW
Messages postés
4764
Date d'inscription
dimanche 12 juin 2011
Statut
Contributeur
Dernière intervention
5 octobre 2021
1 295
Modifié par gravgun le 31/01/2015 à 16:10
Modifié par gravgun le 31/01/2015 à 16:10
'lut, à mon avis le crash vient du fait que tu utilises
Il faut donc sauvegarder le pointeur pour ne l'utiliser qu'une fois:
from human import idiocy
del idiocy
va_arg(ap, char*)deux fois dans ton corps de boucle; or
va_arg()non seulement retourne l'argument comme tu le souhaites mais passe aussi au suivant. Du coup tu tentes d'accéder au 3e argument, or tu n'en passes pas; va_arg retournerait donc NULL, et strcpy n'apprécie pas.
Il faut donc sauvegarder le pointeur pour ne l'utiliser qu'une fois:
do {
cout << txt << " " ;
char *ptr = va_arg(ap, char*);
txt = new char[strlen(ptr) + 1];
strcpy(txt, ptr);
} while(txt != NULL || strlen(txt) != 0);
from human import idiocy
del idiocy
Lap-top
Messages postés
56
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
5 octobre 2016
9
31 janv. 2015 à 21:38
31 janv. 2015 à 21:38
Merci pour ta réponse, jai trouvé la solution, aidé par d'autres sur un autre site.
sambia39
Messages postés
610
Date d'inscription
vendredi 31 juillet 2009
Statut
Membre
Dernière intervention
9 février 2023
48
Modifié par sambia39 le 1/02/2015 à 01:35
Modifié par sambia39 le 1/02/2015 à 01:35
Bonsoir
Avez-vous testé le pire des cas ? c'est-à-dire, si je fais ça:
Il est clair que les deux programmes fournis dans les postes précédents sont totalement faux et bogué de partout.
Les erreurs mentionné dans le poste précédent sont toujours d'actualité( erreur de programmation & logique ) et rien n'a été corrigé mieux encore vous avez ajouté un bogue supplémentaire.
partant de là =>
Donc si ma variable pointeur de type caractère
Bref, la fonction doit avoir ce qu'on appelle une sentinelle ou une save flag en clair, elle nous permet de savoir exactement combien d'argument ont été passé ou spécifier l'arrêt du traitement à l'aide d'une valeur spéciale en tant que derniers arguments de plus le premier argument fixe de notre fonction n'est pas utilisé mais pour c'est genre de fonction, il nous faut au moins un argument.
Au final si on suit cette logique, nous devons avoir une fonction qui affichage toutes les chaines de caractère passé en argument jusqu'à la dernière qui doit être NULL
à bientôt
Celui qui peut, agit. Celui qui ne peut pas, enseigne.
Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien, et les philosophes, qui ne connaissent rien sur tout.
George Bern
Avez-vous testé le pire des cas ? c'est-à-dire, si je fais ça:
CfassOut(NULL, NULL);
Il est clair que les deux programmes fournis dans les postes précédents sont totalement faux et bogué de partout.
Les erreurs mentionné dans le poste précédent sont toujours d'actualité( erreur de programmation & logique ) et rien n'a été corrigé mieux encore vous avez ajouté un bogue supplémentaire.
partant de là =>
CfassOut(NULL, NULL);
size_t strlen( const char *str )renvoi la taille d'une chaine de caractères et @gravgun: va_arg retournerait donc NULL, et strcpy n'apprécie pas.
Donc si ma variable pointeur de type caractère
char *ptrest nul parce que la fonction
va_arg(ap, char*);ma retourner NULL je n'en tien surtout pas compte et j'alloue tout de même de la mémoire a ma variable pointeur de type char
char* txt = first;qui ne pointe plus ( désormais) sur premier argument de ma fonction
void CfassOut(char *first, ...);dont celle-ci (
char* txt), réserve bien NULL comme taille mémoire souhaité que je tiens toujours pas compte pour ensuite copier le contenue de ma variable pointeur
ptrdans le variable pointeur
txtet au final comme en teste au moins une fois en est sûr que ça va marcher dans les cas suivant ? :
CfassOut(NULL,NULL); //bogue
CfassOut(NULL,"BONJOUR"); //bogue
/* Compilateur en mode stricte j'obtiens
* deprecated conversion from string constant to `char*' [-Werror=write-strings]
*/
CfassOut("BONJOUR",NULL); //bogue
CfassOut("SALUT","S39"); //bogue
/* cast en (char *) */
CfassOut((char*)"BONJOUR",NULL); //bogue
CfassOut((char*)"SALUT","S39"); //bogue
Bref, la fonction doit avoir ce qu'on appelle une sentinelle ou une save flag en clair, elle nous permet de savoir exactement combien d'argument ont été passé ou spécifier l'arrêt du traitement à l'aide d'une valeur spéciale en tant que derniers arguments de plus le premier argument fixe de notre fonction n'est pas utilisé mais pour c'est genre de fonction, il nous faut au moins un argument.
Au final si on suit cette logique, nous devons avoir une fonction qui affichage toutes les chaines de caractère passé en argument jusqu'à la dernière qui doit être NULL
#include <cstdlib>
#include <cstdarg>
#include <iostream>
/* Fonction multi-argument */
void cFass_Correct( void *p, ... ){
va_list v_list;
va_start( v_list , p );
char *p_str = NULL;
while( (p_str = va_arg( v_list, char* ) ) != NULL ){
std::cout << "[ARG]\t:" << p_str << std::endl;
p_str = NULL;
}
}
/* Fonction principal */
int main( void ){
/* Teste */
cFass_Correct( NULL, NULL );
cFass_Correct( NULL, "BONJOUR", NULL );
cFass_Correct( NULL, "BONJOUR\n", "S39", NULL );
cFass_Correct( NULL, "BONJOUR", NULL, "S39" ); /* affiche bonjour */
cFass_Correct( (char*)"BONJOUR", NULL );
cFass_Correct( (char*)"BONJOUR", "S39", NULL );
return ( EXIT_SUCCESS );
}
à bientôt
Celui qui peut, agit. Celui qui ne peut pas, enseigne.
Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien, et les philosophes, qui ne connaissent rien sur tout.
George Bern
Lap-top
Messages postés
56
Date d'inscription
vendredi 9 décembre 2011
Statut
Membre
Dernière intervention
5 octobre 2016
9
6 févr. 2015 à 21:40
6 févr. 2015 à 21:40
Là, c'est une explication de taille. Vraiment merci d'avoir pris la peine de me le détailler de la sorte. Bye