Konvertieren von Bool in Text in C ++

93

Vielleicht ist dies eine dumme Frage, aber gibt es eine Möglichkeit, einen booleschen Wert in eine Zeichenfolge umzuwandeln, sodass 1 zu "wahr" und 0 zu "falsch" wird? Ich könnte einfach eine if-Anweisung verwenden, aber es wäre schön zu wissen, ob es eine Möglichkeit gibt, dies mit der Sprache oder den Standardbibliotheken zu tun. Außerdem bin ich ein Pedant. :) :)

Jason Baker
quelle
6
Einwand! Was ist mit Lokalisierung? Warum sollte eine Sprache selbst sprachspezifische Literalkonstanten enthalten?
Valdo
1
@valdo - Ich bin mir ziemlich sicher, dass die Internationalisierung für das Projekt, an dem ich gearbeitet habe, kein Problem war. Zu dieser Zeit war es wahrscheinlich ein Schulprojekt.
Jason Baker

Antworten:

118

Wie wäre es mit der C ++ - Sprache selbst?

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;

AKTUALISIEREN:

Wenn Sie mehr als 4 Codezeilen ohne Konsolenausgabe wünschen, besuchen Sie bitte die Seite von cppreference.com, auf der über std::boolalphaund gesprochen wirdstd::noboolalpha das zeigt die Konsole ausgegeben und erklärt mehr über die API.

Wenn Sie zusätzlich std::boolalphaden globalen Status von ändern std::cout, möchten Sie möglicherweise das ursprüngliche Verhalten wiederherstellen. Weitere Informationen zum Wiederherstellen des Status von finden Sie hierstd::cout .

graham.reeds
quelle
Ich bin ein absoluter Neuling in C ++. Kann mir jemand erklären, wie das funktioniert?
Chucky
4
@Chucky Sie werden nicht verstehen können, wie dies funktioniert, bis Sie die Überladung des Operators verstanden haben . Zu erklären, wie das funktioniert, würde den Rahmen dieser Frage weit sprengen. Sie müssen es entweder als eine andere Frage posten oder vorhandene Antworten auf diese Frage nachschlagen. Ich empfehle letzteres .
Michael Dorst
2
Dies druckt nur Boolesche Werte als Text und konvertiert sie nicht in Text / Zeichenfolge.
AtoMerz
Inwiefern scheitert dies an den vom OP vorgegebenen Kriterien "Konvertieren eines Booleschen Werts in eine Zeichenfolge"?
Graham.reeds
2
Dieser Code konvertiert keinen Booleschen Wert in einen String. Erstellen Sie eine Variable std::string strund speichern Sie das Ergebnis der Konvertierung, wenn Sie können.
Rozina
76

Wir sprechen über C ++, oder? Warum um alles in der Welt verwenden wir immer noch Makros?

C ++ - Inline-Funktionen bieten die gleiche Geschwindigkeit wie ein Makro, mit dem zusätzlichen Vorteil der Typensicherheit und der Parameterbewertung (wodurch das von Rodney und dwj erwähnte Problem vermieden wird.

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

Abgesehen davon habe ich ein paar andere Probleme, besonders mit der akzeptierten Antwort :)

// 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;
}

Prost :)


@ DrPizza: Fügen Sie eine ganze Boost-Bibliothek für eine so einfache Funktion ein? Du willst mich doch veräppeln?

ABl.
quelle
@ NathanFellman, die akzeptierte Antwort ist zu langsam. Diese kann verbessert werden, stringwenn Zeichenfolgenkonstanten für "true" und "false" in statischen const-Variablen gespeichert sind.
Serge Rogatch
Dies ist eine problematische Antwort, da: 1. Manchmal möchten Sie "Ja" oder "Nein" anstelle von "Richtig oder" Falsch "und manchmal" Erfolg "gegen" Misserfolg "usw. 2. Manchmal möchten Sie Kleinbuchstaben, manchmal Großbuchstaben Fall, irgendwann Titel Fall.
Einpoklum
2
Lesen Sie die Frage, es ist genau das, was angefordert wurde.
ABl.
@einpoklum Nichts hindert Sie daran, so viele Inline-Funktionen für Ihre gewünschten Conversions zu erstellen, wie Sie möchten.
Rozina
2
In einer Krise können Sie tun:cout << (bool_x ? "true": "false") << endl;
Trevor Boyd Smith
22

C ++ verfügt über geeignete Zeichenfolgen, sodass Sie diese auch verwenden können. Sie befinden sich in der Standard-Header-Zeichenfolge. #include <string>, um sie zu verwenden. Keine strcat / strcpy-Pufferüberläufe mehr; keine fehlenden Nullterminatoren mehr; keine unordentliche manuelle Speicherverwaltung mehr; richtig gezählte Zeichenfolgen mit korrekter Wertesemantik.

C ++ kann Bools auch in lesbare Darstellungen konvertieren. Wir haben früher bei den iostream-Beispielen Hinweise darauf gesehen, aber sie sind etwas eingeschränkt, da sie nur den Text auf die Konsole (oder mit fstreams, einer Datei) übertragen können. Glücklicherweise waren die Designer von C ++ keine vollständigen Idioten. Wir haben auch iostreams, die nicht von der Konsole oder einer Datei, sondern von einem automatisch verwalteten Zeichenfolgenpuffer unterstützt werden. Sie werden Stringstreams genannt. #include <sstream>, um sie zu erhalten. Dann können wir sagen:

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();
}

Natürlich wollen wir das alles nicht wirklich tippen. Glücklicherweise verfügt C ++ auch über eine praktische Drittanbieter-Bibliothek namens Boost , die uns hier weiterhelfen kann. Boost hat eine nette Funktion namens lexical_cast. Wir können es so verwenden:

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

Nun ist es wahr zu sagen, dass dies ein höherer Overhead ist als irgendein Makro; Stringstreams behandeln Gebietsschemas, die Sie möglicherweise nicht interessieren, und erstellen eine dynamische Zeichenfolge (mit Speicherzuweisung), während das Makro eine Literalzeichenfolge liefern kann, wodurch dies vermieden wird. Auf der anderen Seite kann die Stringstream-Methode jedoch für sehr viele Konvertierungen zwischen druckbaren und internen Darstellungen verwendet werden. Sie können sie rückwärts laufen lassen; boost :: lexical_cast <bool> ("true") macht zum Beispiel das Richtige. Sie können sie mit Zahlen und tatsächlich jedem Typ mit den richtig formatierten E / A-Operatoren verwenden. Sie sind also sehr vielseitig und nützlich.

Und wenn nach all dem Ihre Profilerstellung und Ihr Benchmarking ergeben, dass die lexical_casts ein inakzeptabler Engpass sind , sollten Sie in Betracht ziehen, einen Makro-Horror zu machen.

DrPizza
quelle
3
boost :: lexical_cast <bool> ("true") scheint eine bad_lexical_cast-Ausnahme auszulösen
User
3
funktioniert in meiner App nicht "isExist:" + boost :: lexical_cast <std :: string> (isExit)); Ergebnisse isExist: 0
Scott 23 理论
7

Das sollte in Ordnung sein:


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

Aber wenn Sie es mehr C ++ - ish machen wollen:


#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";
}
Shadow2531
quelle
5

Wenn Sie sich für die Verwendung von Makros entscheiden (oder C für ein zukünftiges Projekt verwenden), sollten Sie in der Makroerweiterung Klammern um das 'b' einfügen (ich habe noch nicht genügend Punkte, um den Inhalt anderer Personen zu bearbeiten):

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

Dies ist eine defensive Programmiertechnik , die vor versteckten Fehlern in der Reihenfolge der Operationen schützt. dh wie bewertet dies für alle Compiler?

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

verglichen mit

(1 == 2) ? "true" : "false"
dwj
quelle
Noch bevor Sie de 2k rep haben, können Sie den Inhalt anderer Leute bearbeiten. Es wird überprüft, aber natürlich könnten Sie.
SysDragon
2

Ich benutze ein ternäres in einem printf wie diesem:

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

Wenn Sie es makro:

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

Dann müssen Sie sicherstellen, dass alles, was Sie weitergeben 'b', keine Nebenwirkungen hat. Und vergessen Sie nicht die Klammern um, 'b'da sonst Kompilierungsfehler auftreten können.

Nathan Fellman
quelle
Da 'b' in der Makrodefinition nur einmal vorkommt, warum warnen Sie vor Nebenwirkungen?
Postfuturist
2

Mit C ++ 11 können Sie ein Lambda verwenden, um einen etwas kompakteren Code zu erhalten und diese direkt zu verwenden:

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);

Drucke:

string to print -> true
Federico Spinelli
quelle
1

Dieser Beitrag ist alt, aber jetzt können Sie std::to_stringviele Variablen als konvertierenstd::string .

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

Erwan Guiomar
quelle
Sie können dies jedoch tun, wenn Sie dies für eine Bool-Variable tun, wird nur der numerische Wert "1" oder "0" anstelle von "true" oder "false" konvertiert.
David E
1

Ohne den Strom hineinzuziehen:

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

Verwenden Sie boolalphadiese Option, um bool to string zu drucken.

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

C ++ - Referenz

UIResponder
quelle
-5

Ich bin damit einverstanden, dass ein Makro am besten passt. Ich habe gerade einen Testfall erstellt (glauben Sie mir, ich bin nicht gut mit C / C ++, aber das klang lustig):

#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
quelle
-5

Solange Strings direkt als Char-Array angesehen werden können, wird es sehr schwer sein, mich davon zu überzeugen std::string Strings als erstklassige Bürger in C ++ dargestellt werden.

Außerdem scheint es mir sowieso eine schlechte Idee zu sein, Allokation und Begrenztheit zu kombinieren.

Mat Noguchi
quelle
-7

Probieren Sie dieses Makro aus. Überall dort, wo "true" oder "false" angezeigt werden soll, ersetzen Sie es einfach durch PRINTBOOL (var), wobei var der Bool ist, für den Sie den Text möchten.

#define PRINTBOOL(x) x?"true":"false"
Dagorym
quelle
2
Benötigen Sie einige Klammern in diesem Makro, weshalb Sie wahrscheinlich die Abwertung erhalten haben.
Postfuturist