Bool'u C ++ 'da metne dönüştürme


95

Belki bu aptalca bir sorudur, ancak bir boole değerini 1'in "doğru" ya ve 0'ın "yanlış" a döneceği şekilde bir dizeye dönüştürmenin herhangi bir yolu var mı? Sadece bir if ifadesi kullanabilirdim, ancak bunu dil veya standart kitaplıklarla yapmanın bir yolu olup olmadığını bilmek güzel olurdu. Artı, ben bir bilgiçim. :)


6
İtiraz! Yerelleştirme ne olacak? Neden bir dilin kendisi dile özgü değişmez sabitler içerir?
valdo

1
@valdo - Üzerinde çalıştığım proje için uluslararasılaşmanın bir sorun olmadığından oldukça eminim. O zamanlar muhtemelen bir okul projesiydi.
Jason Baker 13

Yanıtlar:


119

C ++ dilinin kendisini kullanmaya ne dersiniz?

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;

GÜNCELLEME:

Herhangi bir konsol çıkışı olmayan 4 satırdan fazla kod istiyorsanız, lütfen cppreference.com'un hakkında konuşulan sayfasına gidin vestd::boolalphastd::noboolalpha bu size konsol çıktısını gösterir ve API hakkında daha fazlasını açıklar.

Ek olarak std::boolalpha, kullanımı genel durumunu değiştirir, std::coutorijinal davranışı geri yüklemek isteyebilirsiniz , durumunu geri yükleme hakkında daha fazla bilgi için buraya gidinstd::cout .


C ++ için tam bir acemiyim. Biri bana bunun nasıl çalıştığını açıklayabilir mi?
Chucky

4
@Chucky Operatör aşırı yüklemesini anlayana kadar bunun nasıl çalıştığını anlayamayacaksınız . Bunun nasıl çalıştığını açıklamak, bu sorunun kapsamının çok ötesinde olacaktır. Ya farklı bir soru olarak göndermeniz ya da bu soruya verilen mevcut cevapları aramanız gerekir. İkincisini tavsiye ederim .
Michael Dorst

2
Bu yalnızca boole'leri metin olarak yazdırır, onları metne / dizeye dönüştürmez.
atoMerz

Öyleyse bu, OP tarafından verilen "bir boole değerini bir dizeye dönüştürme" kriterini ne şekilde başarısız olur?
graham.reeds

2
Bu kod, bir boole'yi dizeye dönüştürmez. Bir değişken oluşturun std::string strve yapabiliyorsanız, dönüşümün sonucunu ona kaydedin.
rozina

78

C ++ hakkında konuşuyoruz değil mi? Neden hala makro kullanıyoruz?

C ++ satır içi işlevler, tür güvenliği ve parametre değerlendirmesinin ek faydasıyla (Rodney ve dwj'nin bahsettiği sorunu ortadan kaldıran) size bir makroyla aynı hızı verir.

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

Bunun dışında, özellikle kabul edilen cevapla ilgili birkaç başka endişem var :)

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

Şerefe :)


@DrPizza: Bu kadar basit bir işlev uğruna tam bir destek kitaplığı ekleyin? Şaka yapıyor olmalısın?


@NathanFellman, kabul edilen cevap çok yavaş. Bu string, "true" ve "false" için dize sabitleri statik sabit değişkenlerinde depolanıyorsa iyileştirilebilir .
Serge Rogatch

Bu sorunlu bir cevaptır, çünkü: 1. Bazen "doğru" veya "yanlış" yerine "evet" veya "hayır" istersiniz ve bazen "başarı" yerine "başarısızlık" vb. 2. Bazen küçük harf, bazen büyük dava, bazen başlık davası.
einpoklum

2
Soruyu oku, tam olarak istenen buydu.
OJ.

@einpoklum Hiçbir şey, istediğiniz dönüşümler için istediğiniz kadar satır içi işlevler oluşturmanıza engel olamaz.
rozina

2
hızlı bir şekilde şunları yapabilirsiniz:cout << (bool_x ? "true": "false") << endl;
Trevor Boyd Smith

22

C ++ uygun dizelere sahiptir, bu yüzden onları da kullanabilirsiniz. Standart başlık dizesindeler. Bunları kullanmak için #include <string>. Artık strcat / strcpy arabellek taşması yok; artık eksik boş sonlandırıcılar yok; artık karmaşık manuel bellek yönetimi yok; uygun değer semantiği ile uygun sayılan dizeler.

C ++, boolleri insan tarafından okunabilir temsillere dönüştürme yeteneğine de sahiptir. Daha önce iostream örneklerinde ipuçlarını gördük, ancak biraz sınırlıdır çünkü metni yalnızca konsola (veya fstreams, bir dosya) aktarabilirler. Neyse ki, C ++ tasarımcıları tamamen aptal değildi; ayrıca konsol veya dosya tarafından değil, otomatik olarak yönetilen bir dize arabelleği tarafından desteklenen iostream'lerimiz var. Bunlara dizi akışı denir. Bunları almak için #include <sstream>. O zaman şunu söyleyebiliriz:

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

Elbette bunların hepsini yazmak istemiyoruz. Neyse ki, C ++ ayrıca burada bize yardımcı olabilecek Boost adlı kullanışlı bir üçüncü taraf kitaplığına sahiptir . Boost'un lexical_cast adında güzel bir işlevi vardır. Bunu şu şekilde kullanabiliriz:

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

Şimdi, bunun bazı makrodan daha yüksek ek yük olduğunu söylemek doğru; dize akışları, umursamayabileceğiniz yerel ayarlarla ilgilenir ve dinamik bir dize (bellek ayırma ile) oluştururken, makro bunu engelleyen bir değişmez dize verebilir. Ancak kapak tarafında, dizgi akışı yöntemi, yazdırılabilir ve dahili gösterimler arasında çok sayıda dönüşüm için kullanılabilir. Geriye doğru koşabilirsiniz; boost :: lexical_cast <bool> ("true"), örneğin doğru olanı yapar. Bunları sayılarla ve aslında her türden doğru formatlanmış G / Ç operatörleriyle kullanabilirsiniz. Yani oldukça çok yönlü ve kullanışlıdırlar.

Ve tüm bunlardan sonra profil oluşturma ve kıyaslamanız lexical_casts'in kabul edilemez bir darboğaz olduğunu ortaya çıkarsa, işte o zaman makro korku yapmayı düşünmelisiniz.


3
boost :: lexical_cast <bool> ("true") bir bad_lexical_cast istisnası atıyor gibi görünüyor
Kullanıcı

3
benim uygulamamda çalışmıyor, "isExist:" + boost :: lexical_cast <std :: string> (isExit)); sonuçlar isExist: 0
Scott 混合 理论

8

Bu iyi olmalı:


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

Ancak, daha fazla C ++ yapmak istiyorsanız - 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";
}

5

Makro kullanmaya karar verirseniz (veya gelecekteki bir projede C kullanıyorsanız), makro genişletmedeki 'b'nin etrafına parantez eklemelisiniz (henüz başkalarının içeriğini düzenlemek için yeterli noktam yok):

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

Bu, gizli işlem sırası hatalarına karşı koruma sağlayan savunmacı bir programlama tekniğidir; yani, bu tüm derleyiciler için nasıl değerlendirilir ?

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

nazaran

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

2k temsilciniz olmadan önce bile aslında diğer insanların içeriğini düzenleyebilirsiniz. İncelenecek, ancak elbette yapabilirsiniz.
SysDragon

2

Bunun gibi bir printf'de üçlü bir değer kullanıyorum:

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

Makro yaparsanız:

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

'b'herhangi bir yan etkisi olmadığından emin olmanız gerekir . 'b'Derleme hataları alabileceğiniz için , etrafındaki parantezleri de unutmayın .


Makro tanımda 'b' yalnızca bir kez göründüğünden, neden yan etkiler konusunda uyarıyorsunuz?
postfuturist

2

C ++ 11 ile biraz daha kompakt bir kod elde etmek ve yerinde kullanım için bir lambda kullanabilirsiniz:

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

Baskılar:

string to print -> true


1

Ostream'i içine sürüklemeden:

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

1

C ++ 20 std::format("{}"

https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification , varsayılan çıktı biçiminin varsayılan olarak dize olacağını iddia ediyor:

auto s6 = std::format("{:6}", true);  // value of s6 is "true  "

ve:

Mevcut bool sunum türleri şunlardır:

  • none, s: Metinsel gösterimi (doğru veya yanlış veya yerel ayara özgü biçim) çıktıya kopyalar.
  • b, B, c, d, o, x, X: static_cast (değer) değerine sahip tamsayı sunum türlerini kullanır.

İlgili: std :: sprintf gibi string formatlama


0

boolalphaBool'u dizeye yazdırmak için kullanın .

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

C ++ Referansı


0

Peki ya basit:

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

-5

Bir makronun en uygun seçenek olabileceğine katılıyorum. Sadece bir test vakası hazırladım (inan bana C / C ++ ile iyi değilim ama bu kulağa eğlenceli geliyordu):

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

-5

Dizeler doğrudan bir karakter dizisi olarak görülebildiği sürece, dizeleri std::stringC ++ 'da birinci sınıf vatandaşlar olarak temsil ettiğine beni ikna etmek gerçekten zor olacak .

Ayrıca, tahsis ve sınırlamayı birleştirmek zaten bana kötü bir fikir gibi geliyor.


-7

Bu Makroyu deneyin. "Doğru" veya yanlışın görünmesini istediğiniz herhangi bir yerde, onu PRINTBOOL (var) ile değiştirin, burada var, metnin olmasını istediğiniz bool'dur.

#define PRINTBOOL(x) x?"true":"false"

2
Bu makroda bazı parantezlere ihtiyacınız var, muhtemelen bu yüzden olumsuz oy aldınız.
postfuturist
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.