Chuyển đổi bool thành văn bản trong C ++


93

Có thể đây là một câu hỏi ngớ ngẩn, nhưng có cách nào để chuyển đổi giá trị boolean thành một chuỗi sao cho 1 chuyển thành "true" và 0 chuyển thành "false" không? Tôi chỉ có thể sử dụng câu lệnh if, nhưng sẽ rất tuyệt nếu biết có cách nào để làm điều đó với ngôn ngữ hoặc các thư viện tiêu chuẩn. Thêm vào đó, tôi là một người đi dạo. :)


6
Sự phản đối! Còn về nội địa hóa? Tại sao bản thân một ngôn ngữ lại chứa các hằng chữ dành riêng cho ngôn ngữ?
valdo

1
@valdo - Tôi khá chắc rằng đối với dự án mà tôi đang thực hiện, quốc tế hóa không phải là một mối quan tâm. Vào thời điểm đó, nó có thể là một dự án trường học.
Jason Baker

Câu trả lời:


118

Còn việc sử dụng chính ngôn ngữ C ++ thì sao?

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;

CẬP NHẬT:

Nếu bạn muốn có nhiều hơn 4 dòng mã mà không có bất kỳ đầu ra bảng điều khiển nào, vui lòng truy cập trang của cppreference.com nói về std::boolalphavà trangstd::noboolalpha này hiển thị cho bạn đầu ra bảng điều khiển và giải thích thêm về API.

Ngoài ra, việc sử dụng std::boolalphasẽ sửa đổi trạng thái chung của std::cout, bạn có thể muốn khôi phục hành vi ban đầu, hãy truy cập vào đây để biết thêm thông tin về việc khôi phục trạng thái củastd::cout .


Tôi là một người mới hoàn thành với C ++. Ai đó có thể giải thích cho tôi cách hoạt động của nó không?
Chucky

4
@Chucky Bạn sẽ không thể hiểu cách hoạt động của điều này cho đến khi bạn hiểu quá tải toán tử . Việc giải thích cách hoạt động sẽ vượt xa phạm vi của câu hỏi này. Bạn sẽ cần đăng nó dưới dạng một câu hỏi khác hoặc tra cứu các câu trả lời hiện có cho câu hỏi đó. Tôi đề nghị cái sau .
Michael Dorst

2
Điều này chỉ in boolean dưới dạng văn bản, nó không chuyển đổi chúng thành văn bản / chuỗi.
atoMerz

Vậy theo cách nào thì điều này không thực hiện được tiêu chí "chuyển đổi giá trị boolean thành một chuỗi" do OP đưa ra?
graham.reeds

2
Mã này không chuyển đổi boolean thành một chuỗi. Tạo một biến std::string strvà lưu kết quả chuyển đổi vào đó, nếu bạn có thể.
rozina

76

Chúng ta đang nói về C ++ phải không? Tại sao chúng ta vẫn sử dụng macro !?

Các hàm nội tuyến trong C ++ cung cấp cho bạn tốc độ tương tự như macro, với lợi ích bổ sung là đánh giá tham số và an toàn kiểu (giúp tránh vấn đề mà Rodney và dwj đã đề cập.

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

Bên cạnh đó, tôi có một vài điều khác, đặc biệt là với câu trả lời được chấp nhận :)

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

Chúc mừng :)


@DrPizza: Bao gồm toàn bộ lib tăng vì lợi ích của một chức năng đơn giản thế này? Bạn phải đùa?


@NathanFellman, câu trả lời được chấp nhận là quá chậm. Điều này có thể được cải thiện stringnếu hằng số chuỗi cho "true" và "false" được lưu trữ trong các biến hằng số tĩnh.
Serge Rogatch

Đây là một câu trả lời có vấn đề, vì: 1. Đôi khi bạn muốn "có" hoặc "không" hơn là "đúng hoặc" sai ", và đôi khi" thành công "so với" thất bại ", v.v. 2. Đôi khi bạn muốn viết thường, đôi khi viết hoa trường hợp, trường hợp tiêu đề đôi khi.
einpoklum

2
Đọc câu hỏi, đó chính xác là những gì được yêu cầu.
OJ.

@einpoklum Không có gì ngăn cản bạn tạo nhiều hàm nội tuyến cho các chuyển đổi mong muốn như bạn muốn.
rozina

2
trong một cuộc khủng hoảng bạn có thể làm:cout << (bool_x ? "true": "false") << endl;
Trevor Boyd Smith

22

C ++ có các chuỗi thích hợp nên bạn cũng có thể sử dụng chúng. Chúng nằm trong chuỗi tiêu đề chuẩn. #include <string> để sử dụng chúng. Không còn vượt quá bộ đệm strcat / strcpy; không còn thiếu các dấu chấm hết rỗng; không còn quản lý bộ nhớ thủ công lộn xộn; chuỗi được đếm thích hợp với ngữ nghĩa giá trị thích hợp.

C ++ cũng có khả năng chuyển đổi các bools thành các biểu diễn mà con người có thể đọc được. Chúng tôi đã thấy các gợi ý về nó trước đó với các ví dụ iostream, nhưng chúng hơi hạn chế vì chúng chỉ có thể truyền văn bản vào bảng điều khiển (hoặc với fstreams, một tệp). May mắn thay, những người thiết kế C ++ không hoàn toàn là những kẻ ngốc; chúng tôi cũng có iostream không được hỗ trợ bởi bảng điều khiển hoặc một tệp, mà bởi một bộ đệm chuỗi được quản lý tự động. Chúng được gọi là dòng chuỗi. #include <sstream> để nhận chúng. Sau đó, chúng ta có thể nói:

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

Tất nhiên, chúng tôi không thực sự muốn nhập tất cả những thứ đó. May mắn thay, C ++ cũng có một thư viện bên thứ ba tiện lợi có tên Boost có thể giúp chúng ta ở đây. Boost có một chức năng hay được gọi là lexical_cast. Do đó, chúng ta có thể sử dụng nó:

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

Bây giờ, đúng khi nói rằng đây là chi phí cao hơn một số macro; stringstreams xử lý các ngôn ngữ mà bạn có thể không quan tâm và tạo một chuỗi động (với cấp phát bộ nhớ) trong khi macro có thể mang lại một chuỗi theo nghĩa đen, điều này tránh được điều đó. Nhưng mặt khác, phương pháp dòng chuỗi có thể được sử dụng cho rất nhiều chuyển đổi giữa các biểu diễn có thể in và nội bộ. Bạn có thể chạy ngược lại; boost :: lexical_cast <bool> ("true") làm điều đúng, chẳng hạn. Bạn có thể sử dụng chúng với các số và thực tế là bất kỳ loại nào với các toán tử I / O được định dạng phù hợp. Vì vậy, chúng khá linh hoạt và hữu ích.

Và nếu sau tất cả những điều này, việc lập hồ sơ và điểm chuẩn của bạn tiết lộ rằng lexical_casts là một nút cổ chai không thể chấp nhận được, đó là lúc bạn nên cân nhắc thực hiện một số điều kinh dị vĩ mô.


3
boost :: lexical_cast <bool> ("true") dường như ném ra một ngoại lệ bad_lexical_cast
Người dùng

3
không hoạt động trong ứng dụng của tôi, "isExist:" + boost :: lexical_cast <std :: string> (isExit)); kết quả là Hiện tại: 0
Scott 混合 理论

8

Điều này sẽ ổn:


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

Nhưng, nếu bạn muốn làm điều đó nhiều hơn 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

Nếu bạn quyết định sử dụng macro (hoặc đang sử dụng C cho một dự án trong tương lai), bạn nên thêm dấu ngoặc đơn xung quanh 'b' trong phần mở rộng macro (tôi chưa có đủ điểm để chỉnh sửa nội dung của người khác):

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

Đây là một kỹ thuật lập trình phòng thủ nhằm bảo vệ khỏi các lỗi thứ tự hoạt động ẩn; tức là, điều này đánh giá như thế nào đối với tất cả các trình biên dịch?

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

so với

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

Ngay cả trước khi có đại diện 2k, bạn thực sự có thể chỉnh sửa nội dung của người khác. Nó sẽ được xem xét, nhưng tất nhiên bạn có thể.
SysDragon

2

Tôi sử dụng một con ba ba trong một printf như thế này:

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

Nếu bạn macro nó:

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

thì bạn cần đảm bảo rằng bất cứ thứ gì bạn đưa vào 'b'không có bất kỳ tác dụng phụ nào. Và đừng quên các dấu ngoặc xung quanh 'b'vì bạn có thể gặp lỗi biên dịch.


Vì 'b' chỉ hiển thị một lần trong định nghĩa macro, tại sao bạn lại cảnh báo về các tác dụng phụ?
postfuturist 25/10/08

2

Với C ++ 11, bạn có thể sử dụng lambda để nhận mã nhỏ gọn hơn một chút và sử dụng tại chỗ:

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

Bản in:

string to print -> true


1

Mà không cần kéo ostream vào đó:

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


0

Làm thế nào về đơn giản:

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

-5

Tôi đồng ý rằng một macro có thể phù hợp nhất. Tôi vừa hoàn thành một trường hợp thử nghiệm (tin rằng tôi không giỏi C / C ++ nhưng điều này nghe có vẻ thú vị):

#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

Miễn là các chuỗi có thể được xem trực tiếp như một mảng char thì sẽ rất khó để thuyết phục tôi rằng std::stringđại diện cho các chuỗi là công dân hạng nhất trong C ++.

Bên cạnh đó, kết hợp phân bổ và giới hạn dường như là một ý tưởng tồi đối với tôi.


-7

Hãy thử Macro này. Bất kỳ nơi nào bạn muốn "true" hoặc false hiển thị, chỉ cần thay thế nó bằng PRINTBOOL (var) trong đó var là bool mà bạn muốn văn bản.

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

2
Cần một số dấu ngoặc đơn trong macro đó, đó có thể là lý do tại sao bạn nhận được phiếu phản đối.
postfuturist 25/10/08
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.