Fonctions à paramètres infinis
Lap-top
Messages postés
56
Date d'inscription
Statut
Membre
Dernière intervention
-
Lap-top Messages postés 56 Date d'inscription Statut Membre Dernière intervention -
Lap-top Messages postés 56 Date d'inscription Statut Membre Dernière intervention -
Bonjour tout le monde, je voudrais créer une fonction qui prend une infinité de paramètres (chaines de caractères) et les affiche sur l'écran de la console. J'ai donc essayé ça mais le programme plante à chaque fois, voici le code :
Merci d'avance.
EDIT: Spécification du langage dans la coloration syntaxique.
void CfassOut(char *first, ...){ char* txt = first; va_list ap; va_start(ap, first); do { cout << txt << " " ; txt = new char[strlen(va_arg(ap, char*)) + 1]; strcpy(txt, va_arg(ap, char*)); }while(txt != NULL || strlen(txt) != 0); cout << endl; va_end(ap); }
int main() { CfassOut("Nick", "Cephas"); }
Merci d'avance.
EDIT: Spécification du langage dans la coloration syntaxique.
A voir également:
- Fonctions à paramètres infinis
- Parametres de mon ordinateur - Guide
- Paramètres dns - Guide
- Paramètres de confidentialité - Guide
- Le bon coin mon compte parametres - Guide
- Paramètres iphone - Guide
3 réponses
'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
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