Найпростіший спосіб перетворення int в рядок в C ++


1573

Який найпростіший спосіб перетворити з intеквівалента stringв C ++. Мені відомі два методи. Чи є простіший спосіб?

(1)

int a = 10;
char *intStr = itoa(a);
string str = string(intStr);

(2)

int a = 10;
stringstream ss;
ss << a;
string str = ss.str();

4
Я думаю, що обидва методи, які ви дали, - це хороші рішення. це залежить від контексту, де вам це потрібно зробити. Якщо ви вже працюєте з потоками, наприклад, читаючи або пишете файл, то ваш другий метод є найкращим. Якщо вам потрібно передати int як рядок до аргументу функції, то itoa може бути простим способом. Але більшість часу перетворення int в рядки відбувається при роботі з файлами, тому потоки є відповідними.
Чарльз Брунет

41
Як варіант 1 взагалі працює для вас? На мій погляд, це itoa()три параметри.
b1nary.atr0phy

1
itoa буде швидше, ніж еквівалент потоку. Існують також способи повторного використання буфера рядків методом itoa (уникаючи виділень купи, якщо ви часто генеруєте рядки. Наприклад, для швидкого оновлення числового виводу). Крім того, ви можете створити користувальницьку потокову програму, щоб зменшити частину накладних витрат тощо. Побудова потоку в першу чергу також не є дешевим підприємством.
Піт

6
@Pete: Після того, як ви почнете турбуватися про те, що швидше, ви захочете подивитися на stackoverflow.com/questions/4351371/…
Ben Voigt

20
Зауважте, що itoa () не є частиною стандарту, а тому за допомогою нього робить ваш код не портативним, оскільки не всі компілятори підтримують його. Для Linux ви, звичайно, не в курсі, якщо не використовуєте щось інше, ніж GCC, що не підтримує цю функцію. Якщо у вас є C ++ 0x, перейдіть до того, що запропонував @Matthieu у своїй відповіді. Якщо це не так, перейдіть до stringstream, оскільки це добре підтримується функція, і ваш код повинен бути сумісним з кожним компілятором C ++. Як альтернативу, ви завжди можете перейти з sprintf ().
rbaleksandar

Відповіді:


2098

C ++ 11 вводить std::stoi(і варіанти для кожного числового типу) і std::to_string, аналоги C atoiі, itoaале виражені в терміні std::string.

#include <string> 

std::string s = std::to_string(42);

тому це найкоротший шлях, про який я можу придумати. Можна навіть пропустити назву типу, використовуючи autoключове слово:

auto s = std::to_string(42);

Примітка: див. [String.conversions] ( 21,5 в n3242 )


199
to_stringне є членом stdвиправлення: stackoverflow.com/questions/12975341/…
Бен

36
Або залежно від вашого компілятора, просто встановіть правильний стандарт мови:g++ -std=c++11 someFile.cc
Thomas M. DuBuisson

12
@Steve: це повинно бути. Він є членом stdкожного компілятора, про якого я знаю, крім одного.
Mooing Duck

5
@Matthiew M. Я використовую те саме, що ви пропонуєте, але я отримую цю помилку: Error : No instance of overloaded function "std::to_string" matches the argument list я використовую VS2010 c ++

19
@ Flying: під VS2010 ви повинні явно передати ціле число, що перетворюється, на один із таких типів [_Longlong, _ULonglong, long double]; тобто:string s = to_string((_ULonglong)i);
Зак

184

Підібравши дискусію з @ v.oddou через пару років, C ++ 17 нарешті запропонував спосіб зробити оригінально-магнетичне рішення на основі макросу (збережене нижче), не проходячи через макро потворність.

// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
    std::ostringstream sstr;
    // fold expression
    ( sstr << std::dec << ... << args );
    return sstr.str();
}

Використання:

int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );

Оригінальна відповідь:

Оскільки "перетворення ... у рядок" є повторюваною проблемою, я завжди визначаю макрос SSTR () у центральному заголовку моїх джерел C ++:

#include <sstream>

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

Використання просте, наскільки це можливо:

int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );

Наведене вище сумісне з C ++ 98 (якщо ви не можете використовувати C ++ 11 std::to_string) і не потребує жодних сторонніх включень (якщо ви не можете використовувати Boost lexical_cast<>); оба ці інші рішення мають кращу продуктивність.


2
Я не дуже знайомий, dynamic_castале я використовую кланг для компіляції, щоб він скаржився на це. Якщо я просто опущу, dynamic_castто вона складається добре; яку мету dynamic_castслужить в цьому випадку? Ми вже створюємо анкету ostringstream, так навіщо це робити?
Меттью

2
@Mathew: Посилання у моїй відповіді веде до детального опису кожної частини конструкції. Поки ми створили a ostringstream, ми зателефонували operator<<()на нього, яке повертається ostream &- для чого .str()не визначено. Мені дуже цікаво, як би Кланг змусив цю роботу без виступу (або чому він створює помилку з цим). Ця конструкція опублікована у багатьох місцях, і я її використовую вже більше десятиліття на багатьох різних компіляторах, включаючи MSVC, GCC та XLC, тому я дуже здивований баламутами.
DevSolar

5
Тільки що прийшов на вечірку з цікавості, і прихильнився. Причина: занадто багато голосів за рішення, яке є неелегантним та, ймовірно, повільним. 1. використання макросів. Я не систематично нахмурююся на жоден макрос, але цей занадто короткий, і кінцеві клієнти завжди бояться повторення аргументу, крім страху перед незахищеними макросами мультиліній. (не захищено do {} в той час, як (0)) 2. dynam_cast. Здається, тут потрібен лише static_cast, якщо ви не хочете стверджувати, що бібліотека справді реалізована так, як ви сподіваєтесь. у такому випадку слід використовувати замість boost :: polymorphic_downcast.
v.oddou

2
@ v.oddou: Звичайно, ти можеш критикувати. Але 1. недійсний - макрос - це єдине твердження, do { } while( 0 )нічого не додав би. З 2. і 3. Ви, мабуть, отримали крапку - це можна зробити зі статичним складом, і, можливо, один із вас майстрів шаблонів може створити «приємніший» інтерфейс. Але, як я вже сказав, це аж ніяк не вигадка самого себе. Погляньте навколо, цей макрос (макрос!) Досить всюдисущий. Це сам випадок POLA. Я можу трохи пограти з цим, щоб зробити його більш "впорядкованим".
DevSolar

1
@ v.oddou: Подивіться, що я знайшов серед речей, які C ++ 17 нам приніс. :-) Я сподіваюся, що вам сподобається оновлена ​​відповідь.
DevSolar

109

Зазвичай я використовую наступний метод:

#include <sstream>

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }

Це детально описано тут .


2
Перш ніж використовувати ss, вам потрібно ss.clear(). Я бачив несподівані результати без цієї ініціалізації.
життєвий баланс

14
@lifebalance: Я ніколи не бачив такої поведінки.
Расул

18
@lifebalance: Вам не потрібно clear()новоствореного ostringstreamоб’єкта. clear()скидає прапор помилки / eof, і ще не було створено жодної умови помилки / eof.
Ремі Лебо

2
@Rasoul NumberToString(23213.123)виробляє, 23213.1коли std::to_string(23213.123)виробляє 23213.123000Що відбувається там?
Killzone Kid

1
@KillzoneKid Це тому, що std 'ostream є стаціонарним (це означає, що будь-яка попередня зміна стану зберігається, як число десяткової цифри), поки цей метод починається зі стану за замовчуванням.
xryl669

85

Мабуть, найпоширеніший простий спосіб перетворює по суті ваш другий вибір у названий шаблон lexical_cast, наприклад, у Boost , тому ваш код виглядає так:

int a = 10;
string s = lexical_cast<string>(a);

Одна з причин цього полягає в тому, що він підтримує і інші ролі (наприклад, у зворотному напрямку працює так само добре).

Також зауважте, що хоча Boost lexical_cast почався як просто запис у потоковий струм, а потім витяг із потоку назад, тепер він має кілька доповнень. Перш за все, додані спеціалізації для досить кількох типів, тому для багатьох поширених типів це значно швидше, ніж використання потокового потоку. По-друге, тепер перевіряє результат, тому (наприклад), якщо ви перетворюєте з рядка в int, він може викинути виняток, якщо рядок містить щось, що не вдалося перетворити на int(наприклад, 1234вдалося б, але 123abcкине) .

Станом на C ++ 11, std::to_stringфункція перевантажена для цілих типів, тож ви можете використовувати код типу:

int a = 20;
std::string s = std::to_string(a);
// or: auto s = std::to_string(a);

Стандарт визначає їх як еквівалентні перетворенню sprintf(використовуючи специфікатор перетворення, який відповідає наданому типу об'єкта, наприклад, %dдля int), у буфер достатнього розміру, а потім створюючи std::stringвміст цього буфера.


2
Приємно, я вважаю за краще відповідь Кевіна, хоча, як він показує, включає простір і імена. Просто незначний захват. :) Хороша робота, хоча!
Джейсон Р. Мік

4
Я б сказав, що це шлях, якщо у вас немає підтримки C ++ 11.
Олексій

40

Якщо у вас встановлено Boost (який слід):

#include <boost/lexical_cast.hpp>

int num = 4;
std::string str = boost::lexical_cast<std::string>(num);

4
Домовились про підвищення установки. Я думаю, що часто не один би форматував рядок. З цією метою я віддаю перевагу boost :: format, наприклад формат ("% 02d", число) .str ()
Вернер Еразм

28

Було б простіше використовувати потокові потоки:

#include <sstream>

int x = 42;          // The integer
string str;          // The string
ostringstream temp;  // 'temp' as in temporary
temp << x;
str = temp.str();    // str is 'temp' as string

Або зробіть функцію:

#include <sstream>

string IntToString(int a)
{
    ostringstream temp;
    temp << a;
    return temp.str();
}

18

Не те, що я знаю, в чистому C ++. Але невелика модифікація того, що ви згадали

string s = string(itoa(a));

повинен працювати, і це досить коротко.


55
itoa()не є стандартною функцією!
карикатурист

4
@cartoonist: Тоді що це?
користувач541686

20
Ця функція не визначена в ANSI-C та C ++. Тому його не підтримує якийсь компілятор, наприклад, g ++.
мультфільм

17

Ви можете використовувати std::to_stringдоступні в C ++ 11, як запропонував Матьє М .:

std::to_string(42);

Або якщо продуктивність є критичною (наприклад, якщо ви робите багато конверсій), ви можете скористатися fmt::format_intз бібліотеки {fmt} для перетворення цілого числа на std::string:

fmt::format_int(42).str();

Або рядок C:

fmt::format_int f(42);
f.c_str();

Останній не здійснює динамічного розподілу пам’яті і є більш ніж у 10 разів швидшим, ніж std::to_stringна показниках Boost Karma. Детальнішу інформацію див. У розділі Швидке перетворення цілих чисел у C ++ .

Зверніть увагу, що обидва є безпечними для потоків.

На відміну від цього std::to_string, fmt::format_intне вимагає C ++ 11 і працює з будь-яким компілятором C ++.

Відмова: Я автор бібліотеки {fmt}.


2
Мені було цікаво твердження про відсутність динамічного розподілу пам’яті, залишаючись безпечним для потоку (повторний абітурієнт), тому я прочитав ваш код - c_str()повертає вказівник на буфер, оголошений всередині fmt::FormatIntкласу - тому повернутий покажчик буде недійсним у крапка з комою - див. також stackoverflow.com/questions/4214153/lifetime-of-temporaries
Soren

1
Так, та сама поведінка, що і з std::string::c_str()(таким чином, називання). Якщо ви хочете використовувати його поза повною виразною конструкцією об'єкта, FormatInt f(42);тоді ви можете використовувати f.c_str()без небезпеки його знищення.
vitaut

1
Я отримую щось дивне, коли намагаюся перетворити з int в рядок за допомогою std :: to_string (num). Якщо я зберігаю результат у змінній і намагаюся отримати доступ до нього, як stringNum [1] або stringNum [n], коли n збільшується, я отримую сміття.
користувач8951490

1
Це, безумовно, правильна відповідь на це питання: ефективний та стандартний код, який не є справжнім.
xryl669

16

sprintf()досить добре для перетворення формату. Потім ви можете призначити отриманий рядок C рядку C ++, як це було зроблено в 1.


1
Хе, так. Однак я зазвичай покладаюся на snprintf () та друзів з будь-якого наслідку під час обробки струн C.
Кидок1986

1
@MatthieuM. Ваш коментар підтверджує, що ви цього не є. Якщо висновок був урізаний через цю межу, то значенням повернення є кількість символів (за винятком закінчуваного нульового байта), які були б записані в заключний рядок, якби було достатньо місця. Таким чином, повернене значення розміру або більше означає, що вихід був усічений. Таким чином, ви називаєте його NULLрозміром з нулем і для отримання необхідного розміру буфера.
користувач1095108

2
@ user1095108: Я думаю, ви помиляєтесь snprintf(зверніть увагу на префікс SNP ) та sprintf(зверніть увагу на префікс SP ). Ви передаєте розмір першому, і він дбає про те, щоб не переповнювати, однак останній не знає розмір буфера і, таким чином, може переповнюватися.
Матьє М.

1
Ідея полягає в тому, щоб snprintfспершу назвати варіант, а sprintfваріант - після цього. Оскільки розмір буфера відомий до того часу, дзвінок sprintfстає повністю безпечним.
користувач1095108

1
@ user1095108 Ага, так. Якщо першого буфера для snprintf недостатньо, повернене значення підказує, що було б достатньо. Я б все-таки використовував snprintf для другого виклику, тому що покладатися на реалізацію sprintf та snprintf для узгодження зайво небезпечно.
mabraham

11

Спочатку включайте:

#include <string>
#include <sstream>

По-друге, додайте метод:

template <typename T>
string NumberToString(T pNumber)
{
 ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

Використовуйте такий метод:

NumberToString(69);

або

int x = 69;
string vStr = NumberToString(x) + " Hello word!."

10

Використання stringstream для перетворення чисел небезпечно!

Див. Http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/, де вказується, що operator<<вставляє відформатований вихід.

Залежно від вашого поточного локального значення, ціле число, що перевищує 3 цифри, може перетворити на рядок у 4 цифри, додавши додатковий роздільник тисяч.

Наприклад, int = 1000може бути перетворений на рядок 1.001. Це може змусити порівняльні операції взагалі не працювати.

Тому я настійно рекомендую скористатися цим std::to_stringспособом. Це простіше і робить те, що ви очікуєте.

Оновлено (див. Коментарі нижче) :

C ++ 17 є std::to_charsальтернативою, що не відрізняється місцевою ефективністю


2
Я погоджуюся, що це серйозна проблема, якщо вам потрібно обмінятися даними. На жаль, також std::to_stringвикористовується поточний локал (див. En.cppreference.com/w/cpp/string/basic_string/to_string , розділ "Примітки"). Практично всі стандартні інструменти (від потокових потоків до sprintf, але також sscanfтощо) використовують поточний локал. Я цього не знав до недавнього часу, коли мене це сильно вдарило. В даний час використовуєш вироби в домашніх умовах, зробити це не важко.
Берт Бріл

У посиланні вище також зазначено, що C ++ 17 надає std :: to_chars як альтернативу, що не залежить від локальної локації.
YesThatIsMyName

На жаль, я затримався на C ++ 11 на наступний рік (цілком покращення вже, на щастя).
Берт Бріль

1
from_chars та to_chars були б ідеальними, але, на жаль, вони не запропонували варіант wchar_t.
gast128

8

Для C ++ 98 є кілька варіантів:

boost/lexical_cast

Boost не є частиною бібліотеки C ++, але містить багато корисних розширень бібліотеки.

lexical_castШаблон функції пропонує зручну і послідовну форму для підтримки спільних перетворень в і з довільних типів , коли вони представлені в вигляді тексту.
- Підвищення документації

#include "boost/lexical_cast.hpp"
#include <string>

int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast<std::string>(x);
    return 0;
}

Що стосується часу виконання, то lexical_castоперація займає приблизно 80 мікросекунд (на моїй машині) при першому перетворенні, а потім значно пришвидшується після цього, якщо це робиться надмірно.


itoa

Ця функція не визначена в ANSI-C і не входить до C ++, але підтримується деякими компіляторами.
- cplusplus.com

Це означає, що gcc/ g++не можна компілювати код за допомогою itoa.

#include <stdlib.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    x_str = itoa(x, x_str, 10); // base 10
    return 0;
}

Немає часу виконання звіту. У мене немає встановленої Visual Studio, яку, як повідомляється, можна компілювати itoa.


sprintf

sprintf є стандартною функцією бібліотеки С, яка працює на C рядках, і є абсолютно вірною альтернативою.

Складає рядок з тим самим текстом, який був би надрукований, якби формат був використаний на printf, але замість того, щоб друкувати, вміст зберігається як рядок C у буфері, вказаному str.
- cplusplus.com

#include <stdio.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    int chars_written = sprintf(x_str, "%d", x);
    return 0;
}

stdio.hЗаголовок не може бути необхідним. Що стосується часу виконання, то sprintfоперація займає близько 40 мікросекунд (на моїй машині) при першому перетворенні, а потім значно пришвидшується після цього, якщо це робиться надмірно.


stringstream

Це основний спосіб бібліотеки C ++ перетворення цілих чисел у рядки, і навпаки. Існують подібні сестринські функції, stringstreamякі додатково обмежують використання потоку, як-от ostringstream. ostringstreamСпеціальне використання повідомляє читачеві вашого коду, що ви тільки маєте намір використовувати <<оператор. Ця функція - це все, що особливо необхідно для перетворення цілого числа в рядок. Дивіться це питання для більш детальної дискусії.

#include <sstream>
#include <string>

int main() {
    int x = 5;
    std::ostringstream stream;
    stream << x;
    std::string x_str = stream.str();
    return 0;
}

Що стосується часу виконання, то ця ostringstreamоперація займає близько 71 мікросекунди (на моїй машині), а потім значно пришвидшується, якщо виконувати зайве, але не на стільки, скільки попередні функції .


Звичайно, є й інші варіанти, і ви навіть можете включити один із них у свою функцію, але це пропонує аналітичний погляд на деякі популярні.


Дякуємо, що доглядали за нами (C ++ 98 користувачів)
A. B

@AB Я не можу повірити, що все ще залишилось C ++ 98 користувачів.
Kotauskas

@VladislavToncharov Якщо ваша робота полягає лише у підтримці застарілого обладнання та коду, ви перебираєте старі речі, використовуючи свіжіші галузеві стандарти. Влітку тому я писав код на Python 2.3.
Джошуа

@JoshuaDetwiler О, забув про це, вибач.
Kotauskas


3

Досить легко додати трохи синтаксичного цукру, який дозволяє складати струни на льоту потокоподібним способом

#include <string>
#include <sstream>

struct strmake {
    std::stringstream s;
    template <typename T> strmake& operator << (const T& x) {
        s << x; return *this;
    }   
    operator std::string() {return s.str();}
};

Тепер ви можете додати все, що завгодно (за умови, що << (std::ostream& ..)для нього визначений оператор ) strmake()і використовувати його замість std::string.

Приклад:

#include <iostream>

int main() {
    std::string x =
      strmake() << "Current time is " << 5+5 << ":" << 5*5 << " GST";
    std::cout << x << std::endl;
}

2

ВИДАЛЕНО. Якщо вам потрібно швидко перетворити ціле число з фіксованою кількістю цифр у char * з лівою підкладкою '0' , це приклад для архітектур малої ендіанської архітектури (всі x86, x86_64 та інші):

Якщо ви перетворюєте двоцифрове число:

int32_t s = 0x3030 | (n/10) | (n%10) << 8;

Якщо ви перетворюєте трицифрове число:

int32_t s = 0x303030 | (n/100) | (n/10%10) << 8 | (n%10) << 16;

Якщо ви перетворюєте чотиризначне число:

int64_t s = 0x30303030 | (n/1000) | (n/100%10)<<8 | (n/10%10)<<16 | (n%10)<<24;

І так далі до семизначних чисел. У цьому прикладі nнаведене ціле число. Після перетворення це представлення рядків можна отримати у вигляді (char*)&s:

std::cout << (char*)&s << std::endl;

ПРИМІТКА. Якщо вам це потрібно в порядку байтів великого ендіанця, я хоч і не перевіряв його, але ось приклад: для трицифрового числа - int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8;для чотиризначних чисел (64-бітний арка): int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32;я думаю, він повинен працювати.


2
А як щодо порядку байтів?
shjeff

Чи не це невизначена поведінка через згладжування вказівника?
dgnuff

1
@shjeff дякую за коментар, я додав у відповідь примітку про витривалість.
Алек

@dgnuff дякую, що вказав на це, хоча у мене з цим проблем не було, ви праві. Я трохи змінив відповідь, щоб вона відповідала Строгим Правилам Збудження, дякую.
Алек

1

Використання:

#define convertToString(x) #x

int main()
{
    convertToString(42); // Returns const char* equivalent of 42
}

3
Працює лише з буквальними числами, не оцінює змінний вміст, хоча іноді корисний.
Вовк

Правильно. Але, безумовно, зручний час
maverick9888

1
Працює лише в час компіляції з буквальними числами констант, я думаю, що ОП запитує про динамічне перетворення, використовуючи змінні цілі числа
Ing. Герардо Санчес

0

Я використовую:

int myint = 0;
long double myLD = 0.0;

string myint_str = static_cast<ostringstream*>(&(ostringstream() << myint))->str();
string myLD_str = static_cast<ostringstream*>(&(ostringstream() << myLD))->str();

Він працює на моїх компіляторах g ++ для Windows та Linux.


0

Ось ще один простий спосіб зробити

char str[100];
sprintf(str, "%d", 101);
string s = str;

sprintf добре відомий, щоб вставити будь-які дані в рядок необхідного формату.

Ви можете перетворити char *масив у рядок, як показано у третьому рядку.




0

Використання:

#include<iostream>
#include<string>

std::string intToString(int num);

int main()
{
    int integer = 4782151;

    std::string integerAsStr = intToString(integer);

    std::cout << "integer = " << integer << std::endl;
    std::cout << "integerAsStr = " << integerAsStr << std::endl;

    return 0;
}

std::string intToString(int num)
{
    std::string numAsStr;

    while (num)
    {
        char toInsert = (num % 10) + 48;
        numAsStr.insert(0, 1, toInsert);

        num /= 10;
    }
    return numAsStr;
}

1
Повністю не вдається для n≤0
Toby Speight

-1
string number_to_string(int x) {

    if (!x)
        return "0";

    string s, s2;
    while(x) {
        s.push_back(x%10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return s;
}

1
Дякуємо за цей фрагмент коду, який може надати деяку короткочасну допомогу. Правильне пояснення значно покращило б його довгострокове значення, показавши, чому це хороше рішення проблеми, і зробило б кориснішим майбутнім читачам інші подібні питання. Будь ласка, відредагуйте свою відповідь, щоб додати пояснення, включаючи зроблені вами припущення.
Toby Speight

Повністю не вдається для n≤0
Toby Speight

Додайте коментарі, поясніть свою відповідь, прочитайте, як відповісти .
Аксен П

-1

Якщо ви використовуєте MFC , ви можете використовувати CString:

int a = 10;
CString strA;
strA.Format("%d", a);

8
Ви повинні зауважити, що це розширення лише для Microsoft: msdn.microsoft.com/en-us/library/ms174288.aspx
JonnyJD

1
Мені подобається ідея CString :: Format (). На жаль, це не тільки портативний MS.
Нік

1
Я оновив свою відповідь, щоб включити інформацію з вашого коментаря @JonnyJD, оскільки я продовжую брати участь у цьому за 5 років ..
Tur1ng

-2
char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs, "%d", timeStart.elapsed()/1000);
sprintf(bufMs, "%d", timeStart.elapsed()%1000);

12
протікає пам’ять, -1 від мене
paulm

Це пахне буфером.
Kotauskas

-2
namespace std
{
    inline string to_string(int _Val)
    {   // Convert long long to string
        char _Buf[2 * _MAX_INT_DIG];
        snprintf(_Buf, "%d", _Val);
        return (string(_Buf));
    }
}

Тепер ви можете використовувати to_string(5).


10
Хоча це рішення працює, воно сильно не рекомендується! Імена, що починаються з підкреслення і великої літери, зарезервовані для компілятора, ви ніколи не повинні їх використовувати. Ін'єкції функцій у область stdімен - це теж не те, що ви коли-небудь повинні робити. Крім того, це не здається, що _MAX_INT_DIGце стандартний макрос, тому якщо він визначений неправильно, цей код має великий потенціал спонукання до невизначеної поведінки. -1
iFreilicht

6
Що таке _MAX_INT_DIG і чому він подвоїться?
півня

-2

Я думаю, що використовувати stringstreamдосить просто:

 string toString(int n)
 {
     stringstream ss(n);
     ss << n;
     return ss.str();
 }

 int main()
 {
    int n;
    cin >> n;
    cout << toString(n) << endl;
    return 0;
 }

Про це йшлося у питанні, і, на жаль, досить повільно.
Kotauskas

-3

Для перетворення в рядок ви використовуєте лічильний тип алгоритму. Я отримав цю техніку з програмування комп'ютерів Commodore 64 . Це також добре для ігрового програмування.

  • Ви берете ціле число і приймаєте кожну цифру, зважену потужностями 10. Отже, припустимо, ціле число дорівнює 950.

    • Якщо ціле число дорівнює або перевищує 100 000, віднімаємо 100 000 і збільшуємо лічильник у рядку на ["000000"];
      продовжуйте робити це до тих пір, поки не буде більше цифр на позиції 100 000. Відкиньте ще одну потужність десять.

    • Якщо ціле число дорівнює або перевищує 10 000, віднімаємо 10000 і збільшуємо лічильник у рядку в позиції ["000000"] + 1;
      продовжуйте робити це, поки не буде більше цифр у позиції 10 000.

  • Відкиньте ще одну потужність десять

  • Повторіть візерунок

Я знаю, що 950 занадто малий, щоб використовувати його як приклад, але я сподіваюся, що ви зрозумієте цю ідею.


Не дуже корисно описати алгоритм, а не показати приклад у коді.
cdeerinck
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.