Może to głupie pytanie, ale czy istnieje sposób na przekonwertowanie wartości logicznej na ciąg znaków w taki sposób, że 1 zamienia się w „prawda”, a 0 w „fałsz”? Mógłbym po prostu użyć instrukcji if, ale byłoby miło wiedzieć, czy można to zrobić z językiem lub standardowymi bibliotekami. Poza tym jestem pedantem. :)
93
Odpowiedzi:
Co powiesz na użycie samego języka C ++?
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;
AKTUALIZACJA:
Jeśli chcesz więcej niż 4 linie kodu bez wyjścia konsoli, przejdź do cppreference.com na stronie mówisz
std::boolalpha
istd::noboolalpha
który pokazuje wyjście konsoli i wyjaśnia więcej o API.Dodatkowo użycie
std::boolalpha
zmodyfikuje globalny stanstd::cout
, możesz chcieć przywrócić oryginalne zachowanie, przejdź tutaj, aby uzyskać więcej informacji na temat przywracania stanustd::cout
.źródło
std::string str
i zapisz w niej wynik konwersji, jeśli możesz.Mówimy o C ++, prawda? Dlaczego u licha nadal używamy makr !?
Funkcje wbudowane C ++ zapewniają taką samą szybkość jak makra, z dodatkową zaletą bezpieczeństwa typu i oceny parametrów (co pozwala uniknąć problemu, o którym wspominali Rodney i dwj.
inline const char * const BoolToString(bool b) { return b ? "true" : "false"; }
Poza tym mam kilka innych zastrzeżeń, szczególnie w odniesieniu do zaakceptowanej odpowiedzi :)
// 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; }
Twoje zdrowie :)
@DrPizza: Dołącz całą bibliotekę doładowania ze względu na tak prostą funkcję? Chyba sobie żartujesz?
źródło
string
jeśli stałe łańcuchowe dla „true” i „false” są przechowywane w statycznych zmiennych stałych.cout << (bool_x ? "true": "false") << endl;
C ++ ma odpowiednie ciągi znaków, więc równie dobrze możesz ich używać. Znajdują się w standardowym ciągu nagłówkowym. #include <string>, aby ich użyć. Nigdy więcej przepełnień bufora strcat / strcpy; nigdy więcej brakujących terminatorów zerowych; koniec z niechlujnym ręcznym zarządzaniem pamięcią; odpowiednio policzone ciągi z odpowiednią semantyką wartości.
C ++ ma również możliwość konwertowania wartości logicznych na reprezentacje czytelne dla człowieka. Widzieliśmy wskazówki na ten temat wcześniej w przykładach iostream, ale są one nieco ograniczone, ponieważ mogą wysyłać tekst tylko do konsoli (lub za pomocą fstreams, pliku). Na szczęście projektanci C ++ nie byli kompletnymi idiotami; mamy również iostreamy, które są obsługiwane nie przez konsolę lub plik, ale przez automatycznie zarządzany bufor ciągu. Nazywają się stringstreams. #include <sstream>, aby je pobrać. Wtedy możemy powiedzieć:
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(); }
Oczywiście nie chcemy tego wszystkiego pisać. Na szczęście C ++ ma również wygodną bibliotekę innej firmy o nazwie Boost, która może nam tutaj pomóc. Boost ma fajną funkcję o nazwie lexical_cast. Możemy to wykorzystać w ten sposób:
boost::lexical_cast<std::string>(my_bool)
Otóż, prawdą jest, że jest to większe obciążenie niż niektóre makra; stringstreams radzą sobie z lokalizacjami, o które możesz nie dbać, i tworzą dynamiczny ciąg (z alokacją pamięci), podczas gdy makro może dać literał łańcuchowy, co pozwala uniknąć tego. Ale z drugiej strony metoda stringstream może być używana do wielu konwersji między reprezentacjami drukowanymi i wewnętrznymi. Możesz je cofnąć; boost :: lexical_cast <bool> ("true") robi na przykład właściwą rzecz. Możesz ich używać z liczbami, a właściwie z każdym typem, z odpowiednio sformatowanymi operatorami I / O. Są więc dość wszechstronne i przydatne.
A jeśli po tym wszystkim twoje profilowanie i testy porównawcze ujawnią, że lexical_casts są niedopuszczalnym wąskim gardłem, to wtedy powinieneś rozważyć zrobienie jakiegoś makrorestrora .
źródło
To powinno wystarczyć:
const char* bool_cast(const bool b) { return b ? "true" : "false"; }
Ale jeśli chcesz to zrobić więcej 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"; }
źródło
Jeśli zdecydujesz się użyć makr (lub używasz C w przyszłym projekcie), powinieneś dodać nawias wokół `` b '' w rozwinięciu makra (nie mam jeszcze wystarczającej liczby punktów, aby edytować zawartość innych osób):
#define BOOL_STR(b) ((b)?"true":"false")
Jest to defensywna technika programowania , która chroni przed ukrytymi błędami kolejności operacji; tj. jak to ocenia się dla wszystkich kompilatorów?
1 == 2 ? "true" : "false"
w porównaniu do
(1 == 2) ? "true" : "false"
źródło
Używam trójskładnika w printf takim jak ten:
printf("%s\n", b?"true":"false");
Jeśli zrobisz to makro:
B2S(b) ((b)?"true":"false")
wtedy musisz upewnić się, że wszystko, co mijasz
'b'
, nie ma żadnych skutków ubocznych. I nie zapomnij o nawiasach wokół znaku,'b'
ponieważ mogą wystąpić błędy kompilacji.źródło
W C ++ 11 możesz użyć lambdy, aby uzyskać nieco bardziej zwarty kod i użycie w miejscu:
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);
Wydruki:
string to print -> true
źródło
Ten post jest stary, ale teraz możesz użyć go
std::to_string
do konwersji wielu zmiennych na plikistd::string
.http://en.cppreference.com/w/cpp/string/basic_string/to_string
źródło
Bez wciągania w to ostreama:
constexpr char const* to_c_str(bool b) { return std::array<char const*, 2>{"false", "true "}[b] ; };
źródło
Służy
boolalpha
do drukowania bool na string.std::cout << std::boolalpha << b << endl; std::cout << std::noboolalpha << b << endl;
Dokumentacja w C ++
źródło
A co z prostymi:
constexpr char const* toString(bool b) { return b ? "true" : "false"; }
źródło
Zgadzam się, że najlepiej pasuje makro. Właśnie przygotowałem przypadek testowy (uwierz mi, nie jestem dobry z C / C ++, ale brzmiało to fajnie):
#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; }
źródło
Tak długo, jak ciągi znaków mogą być postrzegane bezpośrednio jako tablica
std::string
znaków, naprawdę trudno będzie mnie przekonać, że reprezentują łańcuchy jako obywatele pierwszej klasy w C ++.Poza tym połączenie alokacji i ograniczenia wydaje mi się i tak złym pomysłem.
źródło
Wypróbuj to makro. Wszędzie tam, gdzie chcesz, aby pojawiło się „prawda” lub fałsz, po prostu zastąp je PRINTBOOL (zmienna), gdzie zmienna jest wartością logiczną, dla której chcesz znaleźć tekst.
#define PRINTBOOL(x) x?"true":"false"
źródło