Как стать автором
Обновить

Комментарии 12

я согласен, что с привычными способами вывода мягко говоря не все так (кстати еще можно скомпилировать

#include <iostream>
int main() {}

с -static-libstdc++ и посмотреть на размер получившегося бинарника)
Однако и std::print не оптимальное решение проблемы. Советую посмотреть хотя бы на https://github.com/cppfastio/fast_io. А в общем случае видимо придется иметь дело с direct io, uring и вот этим всем.

Спасибо, очень интересно было почитать документацию к fast_io. Однако это едва-ли можно назвать general purpose решением: прикручивать форматирование собственных классов в эту библиотеку, видится, очень больно (например, вот так реализуется поддержка std::complex).

Вы меня, конечно, извините, но

fmt::print(std::cout, "The answer is {}.\n", 42);

Это не вывод форматированного текста. Форматированный текс выглядит как у вас показано:

Run on (8 X 2800 MHz CPU s)
CPU Caches:
  L1 Data 32K (x4)
  L1 Instruction 32K (x4)
  L2 Unified 262K (x4)
  L3 Unified 8388K (x1)
Load Average: 1.83, 1.88, 1.82
-----------------------------------------------------------
Benchmark                Time             CPU   Iterations
-----------------------------------------------------------
printf                87.0 ns         86.9 ns      7834009
ostream                255 ns          255 ns      2746434
print                 78.4 ns         78.3 ns      9095989
print_cout            89.4 ns         89.4 ns      7702973
print_cout_sync       91.5 ns         91.4 ns      7903889

Т.е. кроме содержимого необходимо еще указывать формат для каждого поля - выравнивание, размер поля, чем заполнять и т.п.

Строго говоря, оно даже вот так должно выглядеть:

Run on (8 X 2800 MHz CPU s)
CPU Caches:
  L1 Data 32K (x4)
  L1 Instruction 32K (x4)
  L2 Unified 262K (x4)
  L3 Unified 8388K (x1)
Load Average: 1.83, 1.88, 1.82
-----------------------------------------------------------
Benchmark                Time             CPU   Iterations
-----------------------------------------------------------
printf                87.0 ns         86.9 ns      7834009
ostream              255.0 ns        255.0 ns      2746434
print                 78.4 ns         78.3 ns      9095989
print_cout            89.4 ns         89.4 ns      7702973
print_cout_sync       91.5 ns         91.4 ns      7903889

Т.е. целое число 255 должно "добиться" до 255.0 и выровняться по правому краю. А все флоаты должны округлится (или хотя бы обрезаться) до указанного количества десятичных знаков. И тоже выровняться.

Вот это будет вывод форматированного текста.

В целом, все это есть в printf. Но там с локалями проблемы.

Если это есть в srd::format или std::print - ну так и надо все это расписать.

В противном случае заголовок статьи не соответствует содержанию.

Вы серьёзно утверждаете, что разбор форматной строки в run-time предпочтительнее compile-time?

А, хорошо. Я не специалист в Modern C++, увы. Просто меня смутил вот этот пассаж в статье:

Ведь у нас появился std::print, <...> не менее эффективный, чем std::printf

И при этом ни одного упоминания о разнице между временем исполнения, хотя это едва ли не главная причина, почему вывод текста через std::cout вообще изначально появился.

кстати, по поводу размера. в visual c++ вызов std::format() одним махом увеличивает размер exe-файла на 200 KB. и в DLL со стандартной С++ библиотекой эта шаблонная магия лезть отказывается, в отличие от std::printf(). std::print() пока не завезли, но по идее размер уменьшится не должен.

А что по поводу кросс платформенных переносом строк? Как это красиво делать на C++?

Дочитал до этого места.

Если на большинстве Linux и MacOS систем вышеприведенный код выведет ровно то, что мы от него и ожидаем, то на Windows мы обречены увидеть кракозябры, например: ╨ƒ╤Ç╨╕╨▓╨╡╤é, ╬║╧î╧â╬╝╬┐╧é!, как бы мы этого не пытались избежать различными флагами компиляции.

Автор, ЧЯДНТ?

— Что-то с руками?    — Скорее, с головой...
— Что-то с руками?
— Скорее, с головой...

Если в любой unicode-aware OS (и Windows входит в их число начиная примерно с NT 3.1) от этой программы вы увидите “кракозябры”, то проблема совершенно точно не в ключах компиляции...

В консоли по умолчанию получатся "кракозябры"
В консоли по умолчанию получатся "кракозябры"

Исходник в UTF-8, консоль в CP866, "кракозябры" обязаны быть. И проблема определенно не в ключах компиляции, и вообще не имеет отношения ни к компилятору, ни к языку.

Автор, ЧЯДНТ?

Лучше покажите как осуществить ввод юникодной строки. И, например, распечатать коды введенных клавиш. Ну что-то вроде


#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main(){
  setlocale(LC_ALL, "");
  wchar_t str[100];
  wprintf(L"Строка ввода: ");
  wscanf(L"%ls", str);
  for(int i=0; str[i]!=0; i++)wprintf(L"[%lc] = 0x%04X\n", str[i], str[i]);
}

$ ./a.out 
Строка ввода: Привет_κόσμος!         
[П] = 0x041F
[р] = 0x0440
[и] = 0x0438
[в] = 0x0432
[е] = 0x0435
[т] = 0x0442
[_] = 0x005F
[κ] = 0x03BA
[ό] = 0x03CC
[σ] = 0x03C3
[μ] = 0x03BC
[ο] = 0x03BF
[ς] = 0x03C2
[!] = 0x0021

Поскольку с encoding в ISO/IEC 9899 — море implementation-defined моментов, тут сложно предъявлять кому бы то ни было какие бы то ни было претензии, и нет никаких вариантов, кроме как обратиться к официальным источникам по конкретной имплементации. Text and Strings.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории