Conversion de booléen en texte en C ++

93

C'est peut-être une question stupide, mais y a-t-il un moyen de convertir une valeur booléenne en une chaîne telle que 1 devienne «vrai» et 0 devienne «faux»? Je pourrais simplement utiliser une instruction if, mais ce serait bien de savoir s'il existe un moyen de le faire avec le langage ou les bibliothèques standard. De plus, je suis un pédant. :)

Jason Baker
la source
6
Objection! Et la localisation? Pourquoi une langue elle-même contiendrait-elle des constantes littérales spécifiques à une langue?
valdo
1
@valdo - Je suis presque sûr que pour le projet sur lequel je travaillais, l'internationalisation n'était pas un problème. À l'époque, il s'agissait probablement d'un projet scolaire.
Jason Baker

Réponses:

118

Que diriez-vous d'utiliser le langage C ++ lui-même?

bool t = true;
bool f = false;
std::cout << std::noboolalpha << t << " == " << std::boolalpha << t << std::endl;        
std::cout << std::noboolalpha << f << " == " << std::boolalpha << f << std::endl;

METTRE À JOUR:

Si vous voulez plus de 4 lignes de code sans aucune sortie de console, veuillez vous rendre sur la page de cppreference.com qui en parle std::boolalphaetstd::noboolalpha qui vous montre la sortie de la console et en explique plus sur l'API.

En outre, l'utilisation de std::boolalphamodifiera l'état global de std::cout, vous souhaiterez peut-être restaurer le comportement d'origine, cliquez ici pour plus d'informations sur la restauration de l'état destd::cout .

graham.reeds
la source
Je suis un novice complet en C ++. Quelqu'un peut-il m'expliquer comment cela fonctionne?
Chucky
4
@Chucky Vous ne pourrez pas comprendre comment cela fonctionne tant que vous ne comprenez pas la surcharge des opérateurs . Expliquer comment cela fonctionne serait bien au-delà de la portée de cette question. Vous devrez soit le publier comme une question différente, soit rechercher les réponses existantes à cette question. Je recommande ce dernier .
Michael Dorst
2
Cela n'imprime que les booléens sous forme de texte, cela ne les convertit pas en texte / chaîne.
atoMerz
Alors, de quelle manière cela échoue-t-il au critère "convertir une valeur booléenne en chaîne" donné par l'OP?
graham.reeds
2
Ce code ne convertit pas un booléen en chaîne. Créez une variable std::string stret enregistrez-y le résultat de la conversion, si vous le pouvez.
rozina
76

Nous parlons de C ++, non? Pourquoi diable utilisons-nous encore des macros !?

Les fonctions en ligne C ++ vous donnent la même vitesse qu'une macro, avec l'avantage supplémentaire de la sécurité de type et de l'évaluation des paramètres (ce qui évite le problème mentionné par Rodney et dwj.

inline const char * const BoolToString(bool b)
{
  return b ? "true" : "false";
}

En dehors de cela, j'ai quelques autres reproches, en particulier avec la réponse acceptée :)

// this is used in C, not C++. if you want to use printf, instead include <cstdio>
//#include <stdio.h>
// instead you should use the iostream libs
#include <iostream>

// not only is this a C include, it's totally unnecessary!
//#include <stdarg.h>

// Macros - not type-safe, has side-effects. Use inline functions instead
//#define BOOL_STR(b) (b?"true":"false")
inline const char * const BoolToString(bool b)
{
  return b ? "true" : "false";
}

int main (int argc, char const *argv[]) {
    bool alpha = true;

    // printf? that's C, not C++
    //printf( BOOL_STR(alpha) );
    // use the iostream functionality
    std::cout << BoolToString(alpha);
    return 0;
}

À votre santé :)


@DrPizza: Inclure toute une bibliothèque boost pour une fonction aussi simple? Tu plaisantes?

JO.
la source
@NathanFellman, la réponse acceptée est trop lente. Celui-ci peut être amélioré stringsi les constantes de chaîne pour "true" et "false" sont stockées dans des variables const statiques.
Serge Rogatch
C'est une réponse problématique, car: 1. Parfois vous voulez "oui" ou "non" plutôt que "vrai ou" faux ", et parfois" succès "vs" échec "etc. 2. Parfois vous voulez des minuscules, parfois des majuscules cas, parfois cas de titre.
einpoklum
2
Lisez la question, c'est exactement ce qui a été demandé.
JO.
@einpoklum Rien ne vous empêche de créer autant de fonctions en ligne que vous le souhaitez pour les conversions souhaitées.
rozina
2
dans un crunch, vous pouvez faire: cout << (bool_x ? "true": "false") << endl;
Trevor Boyd Smith
22

C ++ a des chaînes appropriées, vous pouvez donc aussi bien les utiliser. Ils sont dans la chaîne d'en-tête standard. #include <string> pour les utiliser. Plus de dépassements de tampon strcat / strcpy; plus de terminateurs nuls manquants; plus de gestion manuelle de la mémoire désordonnée; chaînes comptées correctement avec une sémantique de valeur appropriée.

C ++ a également la capacité de convertir des booléens en représentations lisibles par l'homme. Nous avons vu des indices plus tôt avec les exemples iostream, mais ils sont un peu limités car ils ne peuvent envoyer le texte que vers la console (ou avec fstreams, un fichier). Heureusement, les concepteurs de C ++ n'étaient pas des idiots complets; nous avons également des iostreams qui ne sont pas sauvegardés par la console ou un fichier, mais par un tampon de chaîne géré automatiquement. Ils sont appelés stringstreams. #include <sstream> pour les obtenir. Alors on peut dire:

std::string bool_as_text(bool b)
{
    std::stringstream converter;
    converter << std::boolalpha << b;   // flag boolalpha calls converter.setf(std::ios_base::boolalpha)
    return converter.str();
}

Bien sûr, nous ne voulons pas vraiment taper tout cela. Heureusement, C ++ dispose également d'une bibliothèque tierce pratique nommée Boost qui peut nous aider ici. Boost a une fonction intéressante appelée lexical_cast. On peut l'utiliser ainsi:

boost::lexical_cast<std::string>(my_bool)

Maintenant, il est vrai de dire que c'est une surcharge plus élevée que certaines macro; Les chaînes de caractères traitent des paramètres régionaux dont vous ne vous souciez peut-être pas et créent une chaîne dynamique (avec allocation de mémoire) alors que la macro peut produire une chaîne littérale, ce qui évite cela. Mais d'un autre côté, la méthode stringstream peut être utilisée pour un grand nombre de conversions entre les représentations imprimables et internes. Vous pouvez les exécuter à l'envers; boost :: lexical_cast <bool> ("true") fait la bonne chose, par exemple. Vous pouvez les utiliser avec des nombres et en fait n'importe quel type avec les bons opérateurs d'E / S formatés. Ils sont donc assez polyvalents et utiles.

Et si après tout cela, votre profilage et votre benchmarking révèlent que les lexical_casts sont un goulot d'étranglement inacceptable, c'est à ce moment que vous devriez envisager de faire de l'horreur macro.

DrPizza
la source
3
boost :: lexical_cast <bool> ("true") semble lancer une exception bad_lexical_cast
Utilisateur
3
ne fonctionne pas dans mon application, "isExist:" + boost :: lexical_cast <std :: string> (isExit)); résultats isExist: 0
Scott 混合 理论
8

Cela devrait être bien:


const char* bool_cast(const bool b) {
    return b ? "true" : "false";
}

Mais, si vous voulez le faire plus C ++ - ish:


#include <iostream>
#include <string>
#include <sstream>
using namespace std;

string bool_cast(const bool b) {
    ostringstream ss;
    ss << boolalpha << b;
    return ss.str();
}

int main() {
    cout << bool_cast(true) << "\n";
    cout << bool_cast(false) << "\n";
}
Ombre2531
la source
5

Si vous décidez d'utiliser des macros (ou si vous utilisez C sur un futur projet), vous devez ajouter des parenthèses autour du `` b '' dans l'expansion de la macro (je n'ai pas encore assez de points pour modifier le contenu des autres):

#define BOOL_STR(b) ((b)?"true":"false")

Il s'agit d'une technique de programmation défensive qui protège contre les erreurs cachées d'ordre des opérations; c'est-à-dire, comment cela évalue-t-il pour tous les compilateurs?

1 == 2 ? "true" : "false"

par rapport à

(1 == 2) ? "true" : "false"
dwj
la source
Même avant d'avoir un représentant de 2k, vous pouvez en fait éditer le contenu d'autres personnes. Il sera revu, mais bien sûr vous pourriez.
SysDragon
2

J'utilise un ternaire dans un printf comme ceci:

printf("%s\n", b?"true":"false");

Si vous le macro:

B2S(b) ((b)?"true":"false")

alors vous devez vous assurer que tout ce que vous transmettez 'b'n'a pas d'effets secondaires. Et n'oubliez pas les crochets autour du 'b'car vous pourriez obtenir des erreurs de compilation.

Nathan Fellman
la source
Comme «b» n'apparaît qu'une seule fois dans la définition de la macro, pourquoi mettez-vous en garde contre les effets secondaires?
postfuturiste
2

Avec C ++ 11, vous pouvez utiliser un lambda pour obtenir un code légèrement plus compact et une utilisation sur place:

bool to_convert{true};
auto bool_to_string = [](bool b) -> std::string {
    return b ? "true" : "false";
};
std::string str{"string to print -> "};
std::cout<<str+bool_to_string(to_convert);

Impressions:

string to print -> true
Federico Spinelli
la source
1

Cet article est ancien mais vous pouvez maintenant l'utiliser std::to_stringpour convertir beaucoup de variables enstd::string .

http://en.cppreference.com/w/cpp/string/basic_string/to_string

Erwan Guiomar
la source
Vous pouvez mais si vous faites cela sur une variable booléenne, cela convertira simplement la valeur numérique, "1" ou "0", plutôt que "true" ou "false".
David E
1

Sans y faire glisser ostream:

constexpr char const* to_c_str(bool b) {
   return  
    std::array<char const*, 2>{"false", "true "}[b]
   ;
};
ewd
la source
0

Utilisez boolalphapour imprimer booléen en chaîne.

std::cout << std::boolalpha << b << endl;
std::cout << std::noboolalpha << b << endl;

Référence C ++

UIResponder
la source
0

Que diriez-vous du simple:

constexpr char const* toString(bool b)
{
   return b ? "true" : "false";
}
carlsb3rg
la source
-5

Je suis d'accord qu'une macro pourrait être la meilleure solution. Je viens de créer un cas de test (croyez-moi, je ne suis pas bon avec C / C ++ mais cela semblait amusant):

#include <stdio.h>
#include <stdarg.h>

#define BOOL_STR(b) (b?"true":"false")

int main (int argc, char const *argv[]) {
    bool alpha = true;
    printf( BOOL_STR(alpha) );
    return 0;
}
Joseph Pecoraro
la source
-5

Tant que les chaînes peuvent être vues directement comme un tableau de caractères, il sera vraiment difficile de me convaincre que les std::stringchaînes représentent des citoyens de première classe en C ++.

De plus, combiner allocation et délimitation me semble de toute façon être une mauvaise idée.

Mat Noguchi
la source
-7

Essayez cette macro. Partout où vous voulez que "true" ou false apparaisse, remplacez-le simplement par PRINTBOOL (var) où var est le booléen pour lequel vous voulez le texte.

#define PRINTBOOL(x) x?"true":"false"
dagoryme
la source
2
Besoin de parenthèses dans cette macro, c'est probablement pourquoi vous avez obtenu le vote défavorable.
postfuturiste