С++ эквивалент printf() или форматированного вывода

Я относительно новичок в мире C++. Я знаю, что std::cout используется для вывода на консоль в C++. Но рассмотрим следующий код на C:

#include<stdio.h>

int main(){
    double dNum=99.6678;
    printf("%.02lf",dNum);
    //output: 99.67
 return 0;
}

Как добиться аналогичного форматирования значения типа double до 2 знаков после запятой, используя cout в С++?

Я знаю, что С++ обратно совместим с С. Но есть ли эквивалент printf() в С++, если да, то где он определен?


person Abrar    schedule 25.10.2015    source источник
comment
Используйте setprecision : std::cout << std::fixed << std::setprecision(2) << dNum;   -  person Hatted Rooster    schedule 25.10.2015
comment
Возможный дубликат How to ' cout' правильное количество знаков после запятой в двойном значении?   -  person mpromonet    schedule 25.10.2015


Ответы (9)


Это то, что вы хотите:

std::cout << std::fixed << std::setprecision(2);
std::cout << dNum;

и не забудьте:

#include <iostream>
#include <iomanip>
person vishal    schedule 25.10.2015

Эквивалента нет. Больно использовать cout для форматированного вывода.

Все предлагаемые решения, вызывающие setprecision и подобные, ужасны при использовании длинных форматов.

boost::format не поддерживает некоторые очень приятные функции. Несовместимость с printf. Я до сих пор использую printf, потому что он непревзойденный.

person Peter VARGA    schedule 03.07.2016

Если вы действительно хотите повторно использовать те же методы форматирования, что и в C, вы можете использовать Boost::format, который делает именно это:

cout << boost::format("%.02lf") % dNum;
person Daniel Strul    schedule 25.10.2015
comment
Очень хороший совет. Boost.Format сочетает в себе гибкость стиля C, включая возможность динамического форматирования, с безопасностью типов C++. - person Christian Hackl; 25.10.2015

Но есть ли эквивалент printf() в C++, если да, то где он определен?

Существует предложение стандарта P0645 по добавлению аналогичного средства форматирования в C++. А пока вы можете использовать библиотеку {fmt}, которая реализует это предложение и многое другое:

#include <fmt/core.h>

int main()
  fmt::print("{:.02f}", 99.6678);
}

P0645 и {fmt} используют синтаксис строки формата, подобный Python, который похож на printf, но использует {} в качестве разделителей вместо %.

Также сохраняется информация о типе, поэтому вам не нужны l или другие зашумленные спецификаторы.

person vitaut    schedule 26.12.2018

Сохраните вашу программу как CPP и запустите ее.

Он запускается и печатает ответ.

Потому что C++ также имеет printf() и scanf(), как C.

person Uma Kanth    schedule 25.10.2015
comment
Вы должны быть осторожны, так как printf печатает в stdout, который не обязательно должен быть синхронизирован с cout. Не следует использовать как stdout, так и cout, если вы не знаете, что делаете. - person skyking; 25.10.2015

Вы также можете использовать sprintf в C++ для «печати» в строку, а затем вычислить эту строку. Эта стратегия использует ваш опыт форматирования в стиле printf.

person nicomp    schedule 25.10.2015
comment
Чем это лучше, чем просто использовать printf напрямую? - person Christian Hackl; 25.10.2015

Если вы хотите использовать printf как форматирование, вам, вероятно, следует использовать snprintf (или создать вариант размещения поверх этого). Обратите внимание, что sprintf требует, чтобы вы могли гарантировать, что результат не выйдет за пределы буфера, необходимого для сохранения определенного поведения. С другой стороны, snprintf может гарантировать, что он не переполнит буфер, поскольку вы указываете максимальное количество символов, которые будут записаны в строку (вместо этого он усекает вывод).

Вы даже можете создать что-то, что можно напрямую передать ostream поверх snprintf, автоматически выделив буфер и поместив его в объект, который при уничтожении освобождает эту память. Это в дополнение к методу подачи объекта в ostream завершит его. Что-то вроде (с возможностью улучшения):

struct Format {
    char buf[999];

    Format(fmt, ...) {
        va_list ap;
        va_start(fmt, ap);

        vsnprintf(buf, sizeof(buf), fmt, ap);
        va_end(ap);
    }
 }

 ostream& operator<< (ostream& os, Format const& str);

то вы используете это как:

 cout << Format("The answer is %d", 42) << endl;

Если вы используете библиотеки GNU, вы, конечно, можете использовать printf напрямую, поскольку тогда cout и stdout являются одним и тем же объектом. В противном случае вам, вероятно, следует избегать смешивания stdio и iostreams, так как нет гарантии, что они синхронизированы друг с другом.

person skyking    schedule 25.10.2015
comment
Если вы используете GCC, вы можете указать конструктору __attribute__ ((format (printf, 1, 2))), чтобы получить некоторую проверку компиляции типов. - person jxh; 19.01.2018

Чтобы вывести значение на консоль с помощью C++, вам понадобится глобальный объект ostream cout и оператор ‹‹. endl — еще один глобальный объект ostream, используемый в качестве разрыва строки.

Все они определены в заголовочном файле <iostream>. Вы также можете использовать различные флаги форматирования для управления представлением вывода...

#include<iostream>
using namespace std;

int main() {

    double dNum = 99.6678;

    cout << dNum;
    cout.setf(ios::scientific, ios::floatfield); // format into scientific notation
    cout << dNum;
    cout.precision(8); // change precision
    cout << dNum;

    system("pause");
    return 0;
}
person dspfnder    schedule 25.10.2015

Функциональный эквивалент вашего вызова printf() с использованием std::cout:

 std::cout << fixed << setprecision(2) << dNum;

Необходимо #include <iomanip> и <iostream>.

Эквивалентом printf() в C++ является std::printf(), объявленный в <cstdio>.

Кроме того, благодаря обратной совместимости с C — в частности, C++98 требовался для максимальной обратной совместимости с C89 — printf() C, объявленный в <stdio.h>, также доступен в C++. Обратите внимание, однако, что <stdio.h> устарел (помечен для удаления из будущей версии стандарта C++). Кроме того, не все функции printf(), представленные в C99 (стандарт C 1999 г.) или более поздних версиях, обязательно поддерживаются в C++.

person Peter    schedule 25.10.2015
comment
printf не считается устаревшим. <stdio.h> устарел в пользу <cstdio›, вот и все. - person Christian Hackl; 25.10.2015