LINUX.ORG.RU

Конвертация целого в строку по формату.

 , ,


0

2

В стандарте C++20 это скорее всего можно решить фичами пришедшими из библиотеки fmt. А что изящнее будет выглядеть на C++11?

Суть вопроса следующая. Есть std::string строка. К ней в цикле нужно присоединить целый номер в 4 позиции, пустые заполняются нулями. Например, i = 23, «test0023». Не вывести, а получить переменную std::string.

Первое что гуглится - использование «oimanip» + «stringstream», с использованием временной переменной std::stringstream, в которую пишется значение «0023» с помощью setw и fill, и конвертацией её в std::string. В начале цикла разве что её ещё опустошать нужно, иначе следующим шагом поистыковываться будет «00230024».

Есть ещё способы из стандартной библиотеки для <C++20, но без оперирования нуль-терминированными строками в явном виде?

Перемещено leave из talks

★★★★★

Почему нельзя просто взять fmt из C++20? Либо, на крайняк, Boost Format.

Или ты просто хочешь страдать?

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Почему нельзя просто взять fmt из C++20?

Обратная совместимость с gcc до 4.7.2

Либо, на крайняк, Boost Format.

внешняя либа, слишком жирная для поставленной цели.

Я уже нашёл решение, без страданий. Интересно есть ли более изящное?

grem ★★★★★
() автор топика
Ответ на: комментарий от grem

Обратная совместимость с gcc до 4.7.2

Нахрена? С тех пор уже многие успели детей зачать и в школу отправить. Даже если тебе надо поддерживать старые системы, кто мешает использовать новый компилятор?

hateyoufeel ★★★★★
()
Ответ на: комментарий от fsb4000

который в 7 раз быстрее

Вспоминается старая шутка из Unix Haters Handbook:

Sure It Corrupts Your Files, But Look How Fast It Is!

beastie ★★★★★
()
Ответ на: комментарий от hateyoufeel

Даже если тебе надо поддерживать старые системы, кто мешает использовать новый компилятор?

+100500

fsb4000 ★★★★★
()
Ответ на: комментарий от rumgot

Пока устраивает. Работает и ладно. Просто интересно, может ещё что есть.

grem ★★★★★
() автор топика
Ответ на: комментарий от fsb4000

в C+=1 завезли fmt::format_to который в 7 раз быстрее sprintf

Формирование имени файла это не то место где прямо вот надо спешить:-)

AntonI ★★★★★
()
Ответ на: комментарий от hateyoufeel

Даже если тебе надо поддерживать старые системы, кто мешает использовать новый компилятор?

Отсутствие нового компилятора на старой системе? Заходишь на кластер а там гцц-4.7.2 и новый взять просто неоткуда.

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

Заходишь на кластер а там гцц-4.7.2 и новый взять просто неоткуда.

Что значит «неоткуда»? Инопланетяне украли исходники? Мировое оккупационное жидоправительство запрещает их скачивать?

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Что значит «неоткуда»? Инопланетяне украли исходники?

Какая связь меж исходниками и паролем кластера?

anonymous
()
Ответ на: комментарий от beastie

C+=1

Это не то же самое, что С++.

anonymous
()
Ответ на: комментарий от hateyoufeel

Админских прав нет, локально ставить муторно.

AntonI ★★★★★
()
Ответ на: комментарий от beastie

Ну дак, sprintf и печатает в переменную. Не думал, что в царстве C+=1 всё настолько плохо.

возвращают одно и тоже: https://gcc.godbolt.org/z/Gbjr3a

но по скорости:

libc++: https://quick-bench.com/q/baj_DbQfnG7dq3dGEElaXwUqjfE

libstdc++: https://quick-bench.com/q/dXxwYwAQN0fwkOXTOaeLxRUJcHA

и это с++17 фича, а не std::format который пока не реализован в текущих версиях компилятора…

вот видосик про std::to_chars и std::from_chars: https://www.youtube.com/watch?v=4P_kbF0EbZM

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от beastie

Можно конечно, заимев временную переменную в виде сишной строки, с которой до поры до времени связываться не хотелось бы. Такой вариант я тоже рассматривал.

grem ★★★★★
() автор топика

Классический способ - да, stringstream. Только он дюже медленный. Тебе больше подойдёт snprintf в готовую строку - это короче, быстрее и без реаллокаций.

slovazap ★★★★★
()
Ответ на: комментарий от AntonI

Заходишь на кластер а там гцц-4.7.2 и новый взять просто неоткуда

А я думал, что заходишь на кластер, module load GCC-10 и у тебя свежий компилятор.

AlexVR ★★★★★
()
Последнее исправление: AlexVR (всего исправлений: 1)
Ответ на: комментарий от grem

Можно конечно, заимев временную переменную в виде сишной строки, с которой до поры до времени связываться не хотелось бы. Такой вариант я тоже рассматривал.

Ну так std::string и std::vector<char> тоже вполне себе нормальные обёртки над СИ-строкой.

А так, sprintf, std::stringstream, fmtlib вполне решают твою задачу.

fmtlib так вообще прекрасно используется как git-subtree, или через Conan/CGET/…, или как системный пакет.

AlexVR ★★★★★
()
Последнее исправление: AlexVR (всего исправлений: 1)
Ответ на: комментарий от AlexVR

gcc-4.7.2 и вопрос на русскоязычном форуме практически наверняка означает Astra Linux 1.5 и соответствующее ей бюрократическое окружение, в котором module load означает пересертификацию или в принципе запрещено. Хотя, наверное, если сделать новый компилятор и старое все остальное, чтобы софт не из поставки требовался только для сборки, в некоторых случаях может прокатить. Но не во всех.

roof ★★
()
Последнее исправление: roof (всего исправлений: 1)
Ответ на: комментарий от AlexVR

module load GCC-10

выглядит интересно. а дайте хорошую документашку на это чудо. конкретно интересует где взять модуль для гцц 10, оно умеет скачивать модули из интернетов, может есть какой-то общий репозиторий? гайды какие-то очень многословные и непонятные.

anonymous
()
Ответ на: комментарий от anonymous

google://environment modules google://hpc best practices

Как правило, на вычислительном кластере ОС прибита гвоздями из-за Люстры, Инфинибенда и т.п. Поэтому софт ставят на общий диск, а его выбор происходит за счёт настройки PATH и т.п. переменных окружения. Для упрощения последней задачи и используют module.

Есть ещё такая замечательная штука как EasyBuild

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

а где сами модули взять? я модуль для gcc-10 должен сам написать или его можно откуда-то скачать?

anonymous
()
Ответ на: комментарий от AlexVR

А я думал, что заходишь на кластер, module load GCC-10 и у тебя свежий компилятор.

$ module load GCC-10
ModuleCmd_Load.c(213):ERROR:105: Unable to locate a modulefile for 'GCC-10'
AntonI ★★★★★
()
Ответ на: комментарий от roof

К сожалению, это может быть всё что угодно: включая >=astra1.1, centos 6.9 и основанных на нём соответствующие версии scientific и rocks :(

В centos 7.4, емнип, ситуация не сильно лучше с его gcc 4.8.5.

grem ★★★★★
() автор топика
Ответ на: комментарий от grem

Нет предела бюрократизму гос. органов.

Я даже на Windows 98 могу установить gcc 5.1 с C++14 и он будет работать, а тут на куда более новый линукс нельзя обновить компилятор.

fsb4000 ★★★★★
()
Ответ на: комментарий от anonymous

а какой header я должен был подключить для sprintf и assert?

Да, С++20 всё так же имеет хорошую совместимость с С.

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

в C+=1 завезли fmt::format_to который в 7 раз быстрее sprintf

Один интерфейс в 7 раз быстрее другого интерфейса, ага.

i-rinat ★★★★★
()
Ответ на: комментарий от anonymous

пока C++ совместим с С эти заголовки имеют смысл. Заголовки начинающиеся на c не имеют смысла вообще.

Что и показывает, что их могут удалять, когда .h оставляют

<ciso646> (removed in C++20)
<iso646.h>(deprecated)
fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Тулчейн то можно протащить, но его придётся повсюду с собой таскать - так как всё будет хотеть определённую версию glibc.

grem ★★★★★
() автор топика
Ответ на: комментарий от fsb4000

Ты дурак или прикидываешься? Их удалили (удалят), так как в с++ они не имеют смысла. В отличии от.

anonymous
()
Ответ на: комментарий от grem

надо просто собрать с предыдущей версией glibc или собрать статически.

anonymous
()
Ответ на: комментарий от fsb4000

сишные заголовки нужны для немного другого, когда в си добавляют новую фичу, к ней добавляют новый заголовок, как например <stdbool.h>. ну и вообще сишные заголовки для си, а не для с++.

страуструп считает, что си и с++ должны быть одним языком, поэтому языки будут совместимы, но в с++ лучше использовать плюсовые заголовки.

anonymous
()
Ответ на: комментарий от anonymous

си и с++ должны быть одним языком, поэтому языки будут совместимы

есть заголовочный файл для си

struct explicit {
    int explicit;
}

Как его подключить в с++-файл?

Чтобы не говорить про надуманность проблемы, есть #include <xcb/xkb.h> и в нем есть конкретно эта проблема с с++.

anonymous
()
Ответ на: комментарий от anonymous

ну вот поэтому в с++ и надо включать заголовочные файлы для с++, а не для си. так же как в си надо включать заголовочные файлы для си, а не для с++.

там ещё будет export, да? ещё requires, да? что такое суперсет и что такое субсет надо объяснять?

anonymous
()
Ответ на: комментарий от anonymous

что такое суперсет и что такое субсет надо объяснять?

И что из них что?

Я с тобой не хочу спорить, ты перегибаешь палку. Но си и си++ давно уже разные языки, а не суперсубсеты.

anonymous
()
Ответ на: комментарий от anonymous

они всегда были разными языками, но с++ всегда был совместим с си. не во всём потому что в с++ больше всякого барахла чем в си, отсюда всякие разные несовместимости. но си и с++ - это пара совместимых языков в своём совместимом субсете, иногда даже пишут с/с++ через слеш, но это действительно два языка.

поэтому и странно в один язык включать заголовки от другого, хотя в одном направлении в большинстве случаев это может сработать, но не факт. об \том же и речь.

если так подумать, то и си и с++ - это суперсеты над вот этим субсетом их общей совместимости. ну я так думаю.

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

расскажи чёнить для улучшения моего понимания, я бы послушал.

anonymous
()
Ответ на: комментарий от i-rinat

Один интерфейс в 7 раз быстрее другого интерфейса, ага.

Так точно.

И в iostream и sprintf обязана использоваться locale, что ставит крест на высокой производительности.

в std::format и std::to_chars/std::from_chars не используется locale. (у std::format есть отдельные перегрузки, с locale, но если locale не нужна, то она не будет использоваться, в отличие от sprintf и стримов, где locale будет вызываться обязательно)

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.