Преобразовать число в строку указанной длины в C ++

StackOverflow https://stackoverflow.com/questions/225362

  •  03-07-2019
  •  | 
  •  

Вопрос

У меня есть несколько чисел разной длины (например, 1, 999, 76492 и т. д.), и я хочу преобразовать их все в строки общей длины (например, если длина равна 6, тогда эти строки будут: «000001», «000999», «076492»).

Другими словами, мне нужно добавить правильное количество ведущих нулей к числу.

int n = 999;
string str = some_function(n,6);
//str = '000999'

Есть ли такая функция в C ++?

Это было полезно?

Решение

или используя строковые потоки:

#include <sstream>
#include <iomanip>

std::stringstream ss;
ss << std::setw(10) << std::setfill('0') << i;
std::string s = ss.str();

Я собрал информацию, которую нашел на arachnoid.com , потому что мне нравится Безопасный способ iostreams больше. Кроме того, вы можете одинаково использовать этот код в любом другом потоке вывода.

Другие советы

char str[7];
snprintf (str, 7, "%06d", n);

См. snprintf

Одна вещь, о которой вы можете знать, это потенциальная блокировка, которая может возникнуть при использовании подхода stringstream . В STL, поставляемом с Visual Studio 2008, по крайней мере, есть много блокировок, снятых и выпущенных, поскольку различная информация о локали используется во время форматирования. Это может или не может быть проблемой для вас, в зависимости от того, сколько у вас потоков, которые могут одновременно преобразовывать числа в строки ...

Версия sprintf не берет никаких блокировок (по крайней мере, в соответствии с инструментом мониторинга блокировок, который я сейчас разрабатываю ...) и поэтому может быть «лучше» для использования в одновременные ситуации.

Я заметил это только потому, что мой инструмент недавно выплюнул блокировки 'locale' как одни из самых востребованных для блокировок в моей серверной системе; это стало неожиданностью и может заставить меня пересмотреть подход, который я использовал (то есть вернуться к sprintf из stringstream ) ...

stringstream сделает ( как xtofl указал ). формат повышения более удобен замена для snprintf.

Этот метод не использует ни потоки, ни sprintf. Помимо проблем с блокировкой, потоки снижают производительность и действительно являются излишним. Для потоков накладные расходы обусловлены необходимостью создания буфера пара и потока. Для sprintf издержки возникают из-за необходимости интерпретировать строку формата. Это работает, даже когда n отрицательно или когда строковое представление n длиннее, чем len . Это самое быстрое решение.

inline string some_function(int n, int len)
{
    string result(len--, '0');
    for (int val=(n<0)?-n:n; len>=0&&val!=0; --len,val/=10)
       result[len]='0'+val%10;
    if (len>=0&&n<0) result[0]='-';
    return result;
}

Есть много способов сделать это. Самый простой будет:

int n = 999;
char buffer[256]; sprintf(buffer, "%06d", n);
string str(buffer);

sprintf - это C-подобный способ сделать это, который также работает в C ++.

В C ++ - сочетание форматирования потока строк и потока (см. http: // www .arachnoid.com / cpptutor / student3.html ) выполнит эту работу.

Это старая ветка, но, как fmt может сделать ее стандартной, здесь это дополнительное решение:

#include <fmt/format.h>

int n = 999;

const auto str = fmt::format("{:0>{}}", n, 6);

Обратите внимание, что fmt :: format (" {: 0 > 6} " ;, n) работает одинаково хорошо, когда желаемая ширина известна во время компиляции. Другой вариант - abseil :

#include <absl/strings/str_format.h>

int n = 999;

const auto str = absl::StrFormat("%0*d", 6, n);

И снова возможен abs :: StrFormat ("% 06d " ;, n) . расширенный формат - еще один инструмент для решения этой проблемы:

#include <boost/format.hpp>

int n = 999;

const auto str = boost::str(boost::format("%06d") % n);

К сожалению, спецификатор переменной ширины в качестве аргументов, связанных с оператором % , не поддерживается, это требует настройки строки формата (например, const std :: string fmt = "% 0 " + std :: to_string (6) + " d " ;; ).

С точки зрения производительности abseil и fmt утверждают, что они очень привлекательны и быстрее, чем надстройка. В любом случае все три решения должны быть более эффективными, чем подходы std :: stringstream , и, кроме семейства std :: * printf , они не жертвуют безопасностью типов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top