Mengonversi bool menjadi teks di C ++


94

Mungkin ini pertanyaan bodoh, tetapi adakah cara untuk mengubah nilai boolean menjadi string sehingga 1 berubah menjadi "benar" dan 0 berubah menjadi "salah"? Saya bisa saja menggunakan pernyataan if, tetapi alangkah baiknya mengetahui apakah ada cara untuk melakukannya dengan bahasa atau pustaka standar. Plus, saya seorang pedant. :)


6
Keberatan! Bagaimana dengan pelokalan? Mengapa bahasa itu sendiri mengandung konstanta literal khusus bahasa?
valdo

1
@ Valdo - Saya cukup yakin bahwa untuk proyek yang saya kerjakan, internasionalisasi bukanlah masalah. Pada saat itu, kemungkinan besar itu adalah proyek sekolah.
Jason Baker

Jawaban:


119

Bagaimana kalau menggunakan bahasa C ++ itu sendiri?

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;

MEMPERBARUI:

Jika Anda menginginkan lebih dari 4 baris kode tanpa keluaran konsol, buka halaman cppreference.com yang membahas tentang std::boolalphadanstd::noboolalpha yang menunjukkan keluaran konsol dan menjelaskan lebih lanjut tentang API.

Selain itu, penggunaan std::boolalphaakan mengubah status global std::cout, Anda mungkin ingin memulihkan perilaku asli, buka di sini untuk info selengkapnya tentang memulihkan statusstd::cout .


Saya benar-benar pemula di C ++. Adakah yang bisa menjelaskan kepada saya bagaimana ini bekerja?
Chucky

4
@Chucky Anda tidak akan dapat memahami cara kerjanya sampai Anda memahami kelebihan beban operator . Menjelaskan cara kerjanya akan jauh di luar cakupan pertanyaan ini. Anda harus mengeposkannya sebagai pertanyaan lain, atau mencari jawaban yang ada untuk pertanyaan itu. Saya merekomendasikan yang terakhir .
Michael Dorst

2
Ini hanya mencetak boolean sebagai teks, itu tidak mengubahnya menjadi teks / string.
atoMerz

Jadi dengan cara apa ini gagal dalam kriteria "untuk mengubah nilai boolean menjadi string" yang diberikan oleh OP?
graham.reeds

2
Kode ini tidak mengubah boolean menjadi string. Buat variabel std::string strdan simpan hasil konversinya ke dalamnya, jika Anda bisa.
rozina

77

Kita sedang membicarakan C ++ kan? Kenapa kita masih menggunakan makro !?

Fungsi inline C ++ memberi Anda kecepatan yang sama dengan makro, dengan manfaat tambahan dari keamanan tipe dan evaluasi parameter (yang menghindari masalah yang disebutkan Rodney dan dwj.

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

Selain itu, saya memiliki beberapa keluhan lain, terutama dengan jawaban yang diterima :)

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

Bersulang :)


@DrPizza: Sertakan lib dorongan penuh demi fungsi sederhana ini? Kamu pasti bercanda?


@NathanFellman, jawaban yang diterima terlalu lambat. Yang ini bisa diperbaiki stringjika konstanta string untuk "true" dan "false" disimpan dalam variabel konstanta statis.
Serge Rogatch

Ini adalah jawaban yang bermasalah, karena: 1. Terkadang Anda menginginkan "ya" atau "tidak" daripada "benar atau" salah ", dan terkadang" berhasil "vs" gagal "dll. 2. Terkadang Anda menginginkan huruf kecil, terkadang lebih tinggi kasus, kadang kasus judul.
einpoklum

2
Baca pertanyaannya, persis seperti yang diminta.
OJ.

@einpoklum Tidak ada yang menghentikan Anda untuk membuat sebanyak mungkin fungsi inline untuk konversi yang Anda inginkan.
rozina

2
dalam krisis yang dapat Anda lakukan:cout << (bool_x ? "true": "false") << endl;
Trevor Boyd Smith

22

C ++ memiliki string yang tepat sehingga Anda sebaiknya menggunakannya. Mereka ada di string header standar. #include <string> untuk menggunakannya. Tidak ada lagi strcat / strcpy buffer overruns; tidak ada lagi terminator nol yang hilang; tidak ada lagi manajemen memori manual yang berantakan; string yang dihitung dengan benar dengan semantik nilai yang tepat.

C ++ memiliki kemampuan untuk mengubah bools menjadi representasi yang dapat dibaca manusia juga. Kami melihat petunjuk sebelumnya dengan contoh iostream, tetapi mereka agak terbatas karena mereka hanya dapat meledakkan teks ke konsol (atau dengan fstreams, file). Untungnya, para perancang C ++ tidak sepenuhnya idiot; kami juga memiliki iostreams yang tidak didukung oleh konsol atau file, tetapi oleh buffer string yang dikelola secara otomatis. Mereka disebut aliran string. #include <sstream> untuk mendapatkannya. Kemudian kita bisa mengatakan:

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

Tentu saja, kami tidak ingin mengetik semua itu. Untungnya, C ++ juga memiliki pustaka pihak ketiga yang nyaman bernama Boost yang dapat membantu kami di sini. Boost memiliki fungsi bagus yang disebut lexical_cast. Kita bisa menggunakannya sebagai berikut:

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

Sekarang, benar untuk mengatakan bahwa ini adalah overhead yang lebih tinggi daripada beberapa makro; stringstream menangani lokal yang mungkin tidak Anda pedulikan, dan membuat string dinamis (dengan alokasi memori) sedangkan makro dapat menghasilkan string literal, yang menghindarinya. Tapi di sisi lain, metode stringstream dapat digunakan untuk banyak konversi antara representasi yang dapat dicetak dan internal. Anda bisa menjalankannya mundur; boost :: lexical_cast <bool> ("true") melakukan hal yang benar, misalnya. Anda dapat menggunakannya dengan angka dan bahkan tipe apa pun dengan operator I / O yang diformat dengan benar. Jadi mereka cukup serbaguna dan berguna.

Dan jika setelah semua ini profiling dan benchmarking mengungkapkan bahwa lexical_casts adalah bottleneck tidak dapat diterima, itulah saat Anda harus mempertimbangkan melakukan beberapa horor makro.


3
boost :: lexical_cast <bool> ("true") tampaknya memunculkan pengecualian bad_lexical_cast
Pengguna

3
tidak berfungsi di aplikasi saya, "isExist:" + boost :: lexical_cast <std :: string> (isExit)); Hasilnya adalah Exist: 0
Scott 混合 理论

8

Ini seharusnya baik-baik saja:


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

Tetapi, jika Anda ingin melakukannya lebih banyak 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";
}

5

Jika Anda memutuskan untuk menggunakan makro (atau menggunakan C pada proyek mendatang) Anda harus menambahkan tanda kurung di sekitar 'b' dalam perluasan makro (Saya belum memiliki cukup poin untuk mengedit konten orang lain):

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

Ini adalah teknik pemrograman defensif yang melindungi dari kesalahan urutan operasi yang tersembunyi; yaitu, bagaimana evaluasi ini untuk semua kompiler?

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

dibandingkan dengan

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

Bahkan sebelum memiliki reputasi 2k, Anda sebenarnya dapat mengedit konten orang lain. Ini akan ditinjau, tetapi tentu saja Anda bisa.
SysDragon

2

Saya menggunakan terner di printf seperti ini:

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

Jika Anda membuatnya menjadi makro:

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

maka Anda perlu memastikan apa pun yang Anda berikan 'b'tidak memiliki efek samping. Dan jangan lupa tanda kurung di sekitar 'b'karena Anda bisa mendapatkan kesalahan kompilasi.


Karena 'b' hanya muncul sekali dalam definisi makro, mengapa Anda memperingatkan efek samping?
postfuturist

2

Dengan C ++ 11 Anda mungkin menggunakan lambda untuk mendapatkan kode yang lebih ringkas dan sebagai tempat penggunaan:

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

Cetakan:

string to print -> true


1

Tanpa menyeret ostream ke dalamnya:

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

0

Gunakan boolalphauntuk mencetak bool ke string.

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

Referensi C ++


0

Bagaimana dengan yang sederhana:

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

0

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

https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification mengklaim bahwa format keluaran default adalah string secara default:

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

dan:

Jenis presentasi bool yang tersedia adalah:

  • none, s: Menyalin representasi tekstual (benar atau salah, atau bentuk khusus lokal) ke keluaran.
  • b, B, c, d, o, x, X: Menggunakan tipe presentasi integer dengan nilai static_cast (nilai).

Terkait: std :: pemformatan string seperti sprintf


-5

Saya setuju bahwa makro mungkin yang paling cocok. Saya baru saja membuat test case (percayalah, saya tidak mahir dengan C / C ++ tapi ini terdengar menyenangkan):

#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

Selama string dapat dilihat secara langsung sebagai array karakter, akan sangat sulit untuk meyakinkan saya yang std::stringmewakili string sebagai warga kelas pertama di C ++.

Selain itu, menggabungkan alokasi dan batasan tampaknya merupakan ide yang buruk bagi saya.


-7

Coba Makro ini. Di mana pun Anda ingin menampilkan "benar" atau salah, ganti saja dengan PRINTBOOL (var) di mana var adalah bool yang Anda inginkan untuk teks tersebut.

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

2
Perlu beberapa tanda kurung di makro itu, yang mungkin itulah sebabnya Anda mendapat suara negatif.
postfuturist
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.