2008-10-22 2 views
30

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

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

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

Есть ли функция, подобная этой в C++?

+12

Как насчет некоторых примеров из следующего: http: /www.codeproject.com/KB/recipes/Tokenizer.aspx Они очень эффективны и несколько элегантны. – 2010-11-02 04:59:42

ответ

44

или с использованием stringstreams:

#include <sstream> 
#include <iomanip> 

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

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

2

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

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

Все град спринтf! – 2008-10-22 11:34:21

+0

в этом случае вы действительно можете использовать: sprintf (buffer, "% 06d", n); обратите внимание на 0 перед 6, которые вам нужны для прокрутки с нулями – 2008-10-22 11:35:18

+0

Буфер размером 256 - это _way_ overkill для этой цели. Несмотря на то, что число может переполнять 7 символов (с которым отвечает Исак, используя snprintf), я все равно не знаю, что занимает 256 символов. :-P – 2008-10-22 11:45:24

1

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

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

3

Этот метод не использует потоки или 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; 
} 
8

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

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

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

Смежные вопросы