อาจจะเป็นคำถามโง่ ๆ แต่มีวิธีใดบ้างที่จะแปลงค่าบูลีนเป็นสตริงเพื่อให้ 1 เปลี่ยนเป็น "จริง" และ 0 เปลี่ยนเป็น "เท็จ" ฉันสามารถใช้คำสั่ง if ได้ แต่คงจะดีหากทราบว่ามีวิธีดำเนินการกับภาษาหรือไลบรารีมาตรฐานหรือไม่ นอกจากนี้ฉันเป็นคนอวดรู้ :)
อาจจะเป็นคำถามโง่ ๆ แต่มีวิธีใดบ้างที่จะแปลงค่าบูลีนเป็นสตริงเพื่อให้ 1 เปลี่ยนเป็น "จริง" และ 0 เปลี่ยนเป็น "เท็จ" ฉันสามารถใช้คำสั่ง if ได้ แต่คงจะดีหากทราบว่ามีวิธีดำเนินการกับภาษาหรือไลบรารีมาตรฐานหรือไม่ นอกจากนี้ฉันเป็นคนอวดรู้ :)
คำตอบ:
แล้วการใช้ภาษา 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;
อัพเดท:
หากคุณต้องการมากกว่า 4 บรรทัดของรหัสโดยไม่ต้องส่งออกคอนโซลใด ๆ โปรดไปที่cppreference.com ของการพูดคุยเกี่ยวกับหน้าstd::boolalpha
และstd::noboolalpha
ซึ่งแสดงให้เห็นว่าคุณเอาท์พุทคอนโซลและอธิบายเพิ่มเติมเกี่ยวกับเอพีไอ
นอกจากนี้การใช้std::boolalpha
จะแก้ไขรัฐทั่วโลกของstd::cout
คุณอาจต้องการที่จะเรียกคืนพฤติกรรมเดิมไปที่นี่สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการฟื้นฟูสถานะของstd::cout
std::string str
และบันทึกผลลัพธ์ของการแปลงหากคุณทำได้
เรากำลังพูดถึง C ++ ใช่ไหม? ทำไมเรายังใช้มาโครบนโลก!?
ฟังก์ชันอินไลน์ C ++ ให้ความเร็วเท่ากับมาโครพร้อมประโยชน์เพิ่มเติมของการประเมินความปลอดภัยและพารามิเตอร์ (ซึ่งหลีกเลี่ยงปัญหาที่ Rodney และ dwj กล่าวถึง
inline const char * const BoolToString(bool b)
{
return b ? "true" : "false";
}
นอกเหนือจากนั้นฉันยังมีอีกสองสามข้อโดยเฉพาะอย่างยิ่งกับคำตอบที่ยอมรับ :)
// 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;
}
ไชโย :)
@DrPizza: รวม lib เพิ่มทั้งหมดเพื่อประโยชน์ของฟังก์ชั่นที่เรียบง่ายนี้หรือไม่? คุณต้องล้อเล่น?
string
หากค่าคงที่ของสตริงสำหรับ "จริง" และ "เท็จ" ถูกเก็บไว้ในตัวแปรคงที่
cout << (bool_x ? "true": "false") << endl;
C ++ มีสตริงที่เหมาะสมดังนั้นคุณอาจใช้มันได้เช่นกัน อยู่ในสตริงส่วนหัวมาตรฐาน #include <string> เพื่อใช้ ไม่มีการโอเวอร์รันบัฟเฟอร์ strcat / strcpy อีกต่อไป ไม่มีเทอร์มิเนเตอร์ว่างที่ขาดหายไปอีกต่อไป ไม่มีการจัดการหน่วยความจำแบบแมนนวลที่วุ่นวายอีกต่อไป สตริงที่ถูกนับที่เหมาะสมพร้อมความหมายของค่าที่เหมาะสม
C ++ มีความสามารถในการแปลงบูลเป็นการแสดงที่มนุษย์อ่านได้ด้วย เราเห็นคำแนะนำก่อนหน้านี้ด้วยตัวอย่าง iostream แต่มีข้อ จำกัด เล็กน้อยเนื่องจากสามารถส่งข้อความไปยังคอนโซลได้เท่านั้น (หรือด้วย fstreams ไฟล์) โชคดีที่นักออกแบบของ C ++ ไม่ได้งี่เง่าสมบูรณ์ เรายังมี iostreams ที่ไม่ได้รับการสนับสนุนจากคอนโซลหรือไฟล์ แต่เป็นบัฟเฟอร์สตริงที่มีการจัดการโดยอัตโนมัติ เรียกว่าสตริงสตรีม #include <sstream> เพื่อรับ จากนั้นเราสามารถพูดว่า:
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();
}
แน่นอนเราไม่ต้องการพิมพ์ทั้งหมดนั้นจริงๆ โชคดีที่ C ++ ยังมีไลบรารีของบุคคลที่สามที่สะดวกชื่อBoostซึ่งสามารถช่วยเราได้ที่นี่ Boost มีฟังก์ชันที่ดีที่เรียกว่า lexical_cast เราสามารถใช้มันได้ดังนี้:
boost::lexical_cast<std::string>(my_bool)
ตอนนี้เป็นเรื่องจริงที่จะบอกว่าค่าใช้จ่ายสูงกว่ามาโครบางตัว stringstreams จัดการกับโลแคลที่คุณอาจไม่สนใจและสร้างสตริงแบบไดนามิก (ด้วยการจัดสรรหน่วยความจำ) ในขณะที่มาโครสามารถให้สตริงตามตัวอักษรซึ่งจะหลีกเลี่ยงสิ่งนั้น แต่ในทางกลับกันเมธอด stringstream สามารถใช้สำหรับการแปลงจำนวนมากระหว่างการพิมพ์และการแสดงภายใน คุณสามารถวิ่งไปข้างหลังได้ boost :: lexical_cast <bool> ("true") ทำในสิ่งที่ถูกต้องเช่น คุณสามารถใช้กับตัวเลขและประเภทใดก็ได้กับตัวดำเนินการ I / O ที่จัดรูปแบบถูกต้อง ดังนั้นจึงค่อนข้างหลากหลายและมีประโยชน์
และหากหลังจากนี้การสร้างโปรไฟล์และการเปรียบเทียบของคุณพบว่า lexical_casts เป็นปัญหาคอขวดที่ไม่สามารถยอมรับได้นั่นคือเวลาที่คุณควรพิจารณาทำมาโครสยองขวัญ
สิ่งนี้น่าจะใช้ได้:
const char* bool_cast(const bool b) {
return b ? "true" : "false";
}
แต่ถ้าคุณต้องการทำ 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";
}
หากคุณตัดสินใจที่จะใช้มาโคร (หรือกำลังใช้ C ในโปรเจ็กต์ในอนาคต) คุณควรเพิ่มวงเล็บรอบ 'b' ในการขยายมาโคร (ฉันยังไม่มีคะแนนเพียงพอที่จะแก้ไขเนื้อหาของคนอื่น):
#define BOOL_STR(b) ((b)?"true":"false")
นี่คือเทคนิคการเขียนโปรแกรมเชิงป้องกันที่ป้องกันข้อผิดพลาดของคำสั่งปฏิบัติการที่ซ่อนอยู่ กล่าวคือสิ่งนี้ประเมินสำหรับคอมไพเลอร์ทั้งหมดอย่างไร?
1 == 2 ? "true" : "false"
เปรียบเทียบกับ
(1 == 2) ? "true" : "false"
ฉันใช้ ternary ใน printf ดังนี้:
printf("%s\n", b?"true":"false");
หากคุณถ่ายมาโคร:
B2S(b) ((b)?"true":"false")
จากนั้นคุณต้องแน่ใจว่าสิ่งที่คุณส่งผ่านไป'b'
นั้นไม่มีผลข้างเคียงใด ๆ และอย่าลืมวงเล็บรอบ ๆ'b'
เนื่องจากคุณอาจได้รับข้อผิดพลาดในการคอมไพล์
ด้วย C ++ 11 คุณอาจใช้แลมบ์ดาเพื่อให้ได้โค้ดที่กะทัดรัดขึ้นเล็กน้อยและในการใช้งาน:
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);
พิมพ์:
string to print -> true
โพสต์นี้เก่า แต่ตอนนี้คุณสามารถใช้std::to_string
เพื่อแปลงตัวแปรจำนวนมากเป็นstd::string
ในการแปลงจำนวนมากของตัวแปรเป็น
http://en.cppreference.com/w/cpp/string/basic_string/to_string
โดยไม่ต้องลาก ostream เข้าไป:
constexpr char const* to_c_str(bool b) {
return
std::array<char const*, 2>{"false", "true "}[b]
;
};
ใช้boolalpha
พิมพ์บูลเป็นสตริง
std::cout << std::boolalpha << b << endl;
std::cout << std::noboolalpha << b << endl;
วิธีง่ายๆ:
constexpr char const* toString(bool b)
{
return b ? "true" : "false";
}
C ++ 20 std::format("{}"
https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specificationอ้างว่ารูปแบบเอาต์พุตเริ่มต้นจะเป็นสตริงโดยค่าเริ่มต้น:
auto s6 = std::format("{:6}", true); // value of s6 is "true "
และ:
ประเภทการนำเสนอบูลที่มีอยู่ ได้แก่ :
- ไม่มี s: คัดลอกการแสดงข้อความ (จริงหรือเท็จหรือรูปแบบเฉพาะโลแคล) ไปยังเอาต์พุต
- b, B, c, d, o, x, X: ใช้ชนิดการนำเสนอจำนวนเต็มพร้อมค่า static_cast (value)
ที่เกี่ยวข้อง: std :: การจัดรูปแบบสตริงเช่น sprintf
ฉันยอมรับว่ามาโครอาจเหมาะสมที่สุด ฉันเพิ่งตีกรณีทดสอบ (เชื่อฉันว่าฉันไม่ดีกับ C / C ++ แต่ฟังดูสนุก):
#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;
}
ตราบใดที่สามารถดูสตริงได้โดยตรงในฐานะอาร์เรย์ char มันจะเป็นการยากมากที่จะโน้มน้าวฉันที่std::string
แสดงถึงสตริงในฐานะพลเมืองชั้นหนึ่งใน C ++
นอกจากนี้การรวมการจัดสรรและการกำหนดขอบเขตดูเหมือนจะเป็นความคิดที่ไม่ดีสำหรับฉัน แต่อย่างใด
ลองใช้มาโครนี้ ทุกที่ที่คุณต้องการให้ "true" หรือ false แสดงขึ้นเพียงแค่แทนที่ด้วย PRINTBOOL (var) โดยที่ var คือบูลที่คุณต้องการให้ข้อความนั้น
#define PRINTBOOL(x) x?"true":"false"