Comments 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?
Только при использовании std::format
, std::print
, ... разбор форматной строки, если я правильно понял, что вы имеете ввиду, происходит в compile-time (см. std::basic_format_string)
А, хорошо. Я не специалист в 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.
Как вывести форматированный текст на экран в C++