Нужна постоянная длина в строках [дубликат]

Ваш Javascript будет выполняться на клиенте, а не на сервере. Это означает, что foo не оценивается на стороне сервера, и поэтому его значение не может быть записано в файл на сервере.

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

Кстати, создание привычки встраивать случайные фрагменты PHP-логики в HTML или Javascript может привести к серьезному запутанному коду. Я говорю от болезненного опыта.

36
задан Brian R. Bondy 1 November 2008 в 23:50
поделиться

8 ответов

или используя stringstreams:

#include <sstream>
#include <iomanip>

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

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

50
ответ дан Ivan Mushketyk 25 August 2018 в 12:29
поделиться
  • 1
    FYI - для этого требуются файлы include sstream и iomanip. – Gareth 20 March 2014 в 22:21
  • 2
    И stringstream, setw и setfill (а также string) находятся в пространстве имен std. – rafalcieslak 9 January 2015 в 14:32
  • 3
    В таких ответах я всегда показывал, что такое выход. В этом случае, если int i=1;, это 0000000001. – nakulchawla09 30 April 2018 в 00:17

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

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

1
ответ дан Chris Johnson 25 August 2018 в 12:29
поделиться

stringstream будет делать (, как указал xtofl ). Формат ускорения - более удобная замена для snprintf.

3
ответ дан Community 25 August 2018 в 12:29
поделиться

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

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

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

8
ответ дан Len Holgate 25 August 2018 в 12:29
поделиться
  • 1
    Имеет смысл, что язык используется, но действительно, что он заблокирован ... Ценная информация, которая есть! – xtofl 22 October 2008 в 20:31
  • 2
    Это может быть только Visual Studio STL, которые делают это, я не проверял с помощью тестовой программы, построенной с помощью STLPort. Я также не исследовал, почему он заблокирован. – Len Holgate 22 October 2008 в 22:19
  • 3
    STLPort 5.1.5 не демонстрирует эту проблему с конфликтом в перекрестном потоке, но стиль преобразования sprintf все еще примерно в 3 раза быстрее ... – Len Holgate 19 December 2008 в 23:26
  • 4
    Здесь интересная публикация Лена Холгейта: lenholgate.com/archives/000824.html – Alessandro Jacopson 21 December 2008 в 10:38

Это старый поток, но поскольку 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) возможно. boost format - еще один инструмент для этой проблемы:

#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 утверждают, что они очень привлекательны и быстрее, чем boost. В любом случае все три решения должны быть более эффективными, чем подходы std::stringstream, и кроме семейства std::*printf, они не жертвуют безопасностью типа.

0
ответ дан lubgr 25 August 2018 в 12:29
поделиться
char str[7];
snprintf (str, 7, "%06d", n);

См. snprintf

11
ответ дан Mateus Rodrigues de Morais 25 August 2018 в 12:29
поделиться
  • 1
    Хотя это хорошая практика всегда использовать snprintf (), это одно из немногих мест, где вы можете безопасно использовать sprintf (). – Mark Baker 22 October 2008 в 13:27
  • 2
    Да, знаю. Но я, как правило, всегда использую snprintf, потому что на самом деле нет причин не делать (разница в производительности незначительна). – Isak Savo 22 October 2008 в 15:04
  • 3
    arg # 2 - size_t, а не len, поэтому это 7, а не 6. Лучше использовать sizeof. – PW. 22 October 2008 в 15:43
  • 4
    Не уверен, что мне что-то не хватает, но я думаю, что он также нуждается в типе в строке формата, поэтому & quot;% 06d & quot; или похожие – JSoet 18 November 2015 в 01:05
  • 5
    Первым аргументом snprintf должен быть str, а не buf – Duncan 4 May 2017 в 07:08

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

int n = 999;
char buffer[256]; sprintf(buffer, "%06d", n);
string str(buffer);
2
ответ дан Pramod 25 August 2018 в 12:29
поделиться
  • 1
    Все град спринтф! – Matt Curtis 22 October 2008 в 12:34
  • 2
    в этом случае вы действительно можете использовать: sprintf (buffer, «% 06d», n); обратите внимание на 0 перед 6, которые вам нужны для padd с нулями – Nathan Fellman 22 October 2008 в 12:35
  • 3
    Для этой цели буфером размера 256 является way . Несмотря на то, что число может переполнять 7 символов (с которым отвечает Исак, используя snprintf), я все равно не знаю, что занимает 256 символов. :-П – Chris Jester-Young 22 October 2008 в 12:45
  • 4
    Хороший момент Крис. Я думаю, что наибольший int на самом деле составляет чуть более 999,999,999,999,999, поэтому char buffer [17] совершенно безопасен, что позволяет использовать \ 0 и, возможно, знак (хотя я не думаю, что наибольший отрицательный int был бы где-то рядом с тем длинным). – Matt Curtis 22 October 2008 в 12:52
  • 5
    Самый большой int зависит от реализации. Большинство современных компиляторов используют 32-разрядное дополнение int int, что означает, что наибольший int равен 2,147,483,647, а самый длинный int - min int, -2,147,483,648. Это 12 символов длиной, считая завершающий NUL. Для портативного кода int может быть ЛЮБОЙ длиной. – Steve Jessop 22 October 2008 в 13:01

Этот метод не использует потоки или 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;
}
3
ответ дан sep 25 August 2018 в 12:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: