Перетворення bool в текст на C ++


93

Можливо, це німе запитання, але чи є спосіб перетворити логічне значення в рядок таким чином, щоб 1 перетворився на "true", а 0 перетворився на "false"? Я міг би просто використати оператор if, але було б непогано знати, чи є спосіб зробити це за допомогою мови або стандартних бібліотек. Плюс я педант. :)


6
Заперечення! А як щодо локалізації? Чому сама мова міститиме специфічні для мови буквальні константи?
valdo

1
@valdo - Я майже впевнений, що для проекту, над яким я працював, інтернаціоналізація не турбувала. На той час це, швидше за все, був шкільний проект.
Джейсон Бейкер,

Відповіді:


118

Як щодо використання самої мови 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 який показує вихід консолі і пояснює більше про API.

Крім того, використання std::boolalphaзмінить глобальний стан std::cout, можливо, ви захочете відновити початкову поведінку. Перейдіть сюди, щоб дізнатися більше про відновлення стануstd::cout .


Я повністю новачок у C ++. Хтось може пояснити мені, як це працює?
Чакі

4
@Chucky Ви не зможете зрозуміти, як це працює, поки не зрозумієте перевантаження оператора . Пояснення того, як це працює, було б далеко за межі цього питання. Вам потрібно буде опублікувати його як інше запитання, або переглянути відповіді на це запитання. Я рекомендую останнє .
Майкл Дорст

2
Це лише друкує логічні значення як текст, але не перетворює їх у текст / рядок.
atoMerz

Отже, яким чином це не відповідає критеріям "перетворити логічне значення у рядок", заданим OP?
graham.reeds

2
Цей код не перетворює логічне значення у рядок. Створіть змінну std::string strта збережіть результат перетворення в неї, якщо можете.
rozina

76

Ми говоримо про С ++, правда? Чому ж ми все ще використовуємо макроси !?

Вбудовані функції C ++ забезпечують ту саму швидкість, що і макрос, з додатковою перевагою безпеки типу та оцінки параметрів (що дозволяє уникнути проблеми, про яку згадали Родні та 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: Включити цілий boost lib заради такої простої функції? Ви, мабуть, жартуєте?


@NathanFellman, прийнята відповідь занадто повільна. Цю можна вдосконалити, stringякщо рядкові константи для "true" та "false" зберігаються у статичних змінних const.
Serge Rogatch

Це проблематична відповідь, оскільки: 1. Іноді ви хочете "так" чи "ні", а не "істинно чи" помилково ", а іноді" успіх "проти" невдача "тощо. справа, колись
головна

2
Прочитайте питання, це саме те, про що просили.
ОВ.

@einpoklum Ніщо не заважає вам створити стільки вбудованих функцій для бажаних перетворень, скільки ви хочете.
rozina

2
хрускотом ви можете зробити:cout << (bool_x ? "true": "false") << endl;
Тревор Бойд Сміт

22

C ++ має належні рядки, тому ви можете їх використовувати. Вони знаходяться в стандартному рядку заголовка. #include <string>, щоб використовувати їх. Більше немає перевищення буфера strcat / strcpy; більше немає відсутніх нульових термінаторів; відсутність безладного ручного управління пам'яттю; правильні підраховані рядки з належною семантикою значень.

С ++ також має можливість перетворювати були в читабельні подання. Ми бачили натяки на це раніше на прикладах iostream, але вони дещо обмежені, оскільки вони можуть передавати текст лише на консоль (або з файлом fstreams). На щастя, дизайнери C ++ не були повними ідіотами; ми також маємо iostream, які підтримуються не консоллю чи файлом, а автоматично керованим буфером рядків. Їх називають струнними потоками. #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") робить правильно, наприклад. Ви можете використовувати їх із цифрами та фактично будь-яким типом із правильно відформатованими операторами вводу-виводу. Тож вони досить універсальні та корисні.

І якщо після всього цього ваше профілювання та тестування виявляє, що lexical_casts є неприпустимим вузьким місцем, саме тоді вам слід подумати про макро-жах.


3
boost :: lexical_cast <bool> ("true") видає виняток bad_lexical_cast
Користувач

3
не працює в моєму додатку, "isExist:" + boost :: lexical_cast <std :: string> (isExit)); результати isExist: 0
Скотт 混合 理论

8

Це повинно бути добре:


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

Але, якщо ви хочете зробити це більше на C ++ - іш:


#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

Якщо ви вирішили використовувати макроси (або використовуєте C для майбутнього проекту), вам слід додати дужки навколо 'b' у розширенні макросу (у мене поки що недостатньо точок для редагування вмісту інших людей):

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

Це захисна техніка програмування , яка захищає від прихованих помилок порядку роботи; тобто, як це оцінює всі компілятори?

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

у порівнянні з

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

Навіть перед тим, як повторити де 2k, ви насправді могли редагувати вміст інших людей. Це буде розглянуто, але, звичайно, ви могли б.
SysDragon

2

Я використовую тернар у printf, такий:

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

Якщо ви макрос:

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

тоді вам потрібно переконатися, що все, що ви передасте, 'b'не має жодних побічних ефектів. І не забувайте про дужки навколо, 'b'оскільки ви можете отримати помилки компіляції.


Оскільки "b" відображається лише один раз у визначенні макросу, чому ви попереджаєте про побічні ефекти?
постфутурист

2

З 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

1

Ця публікація стара, але тепер ви можете використовувати std::to_stringдля перетворення великої кількості змінних як std::string.

http://en.cppreference.com/w/cpp/string/basic_string/to_string


Ви можете, але якщо ви зробите це для змінної bool, вона просто перетворить числове значення, "1" або "0", а не "true" або "false".
David E,

1

Не перетягуючи в нього ostream:

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


0

Як щодо простого:

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

-5

Я згоден з тим, що макрос може бути найбільш підходящим. Я просто підготував тестовий приклад (повірте, я не влаштовую 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;
}

-5

Поки рядки можна розглядати безпосередньо як масив символів, буде дуже важко переконати мене, що std::stringпредставляє рядки як громадян першого класу в C ++.

Крім того, поєднання розподілу та обмеженості мені здається поганою ідеєю.


-7

Спробуйте цей макрос. У будь-якому місці, де ви хочете, щоб відображалося "true" або false, просто замініть його на PRINTBOOL (var), де var - це bool, для якого потрібно текст.

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

2
Потрібні деякі дужки в цьому макросі, імовірно, тому ви отримали голос проти.
постфутурист
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.