Converter um número de cadeia de caracteres com um comprimento especificado em C ++

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

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu tenho alguns números de comprimento diferente (como 1, 999, 76492, etc.) e eu quero convertê-los todos para cordas com um comprimento comum (por exemplo, se a duração é de 6, então aquelas cordas será: '000001', '000999', '076492').

Em outras palavras, eu preciso adicionar a quantidade correta de zeros à esquerda para o número.

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

Existe uma função como esta em C ++?

Foi útil?

Solução

ou usando os stringstreams:

#include <sstream>
#include <iomanip>

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

I compilou as informações que encontrei na arachnoid.com porque eu como o de tipo maneira segura de iostreams mais. Além disso, você pode igualmente usar este código em qualquer outro fluxo de saída.

Outras dicas

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

snprintf

Uma coisa que você pode querer estar ciente de é o bloqueio potencial que pode ir em quando você usa a abordagem stringstream. Na STL que acompanha o Visual Studio 2008, pelo menos, há muitos bloqueios retirado e lançado como várias informações localidade é usada durante a formatação. Isto pode, ou não, ser um problema para você, dependendo de quantas linhas você tem que podem ser simultaneamente converter números às cordas ...

A versão sprintf não tomar quaisquer bloqueios (pelo menos de acordo com o bloqueio da ferramenta que eu estou desenvolvendo no momento ... monitoramento) e assim pode ser 'melhor' para uso em situações em simultâneo.

Eu só notei isso porque minha ferramenta recentemente cuspiu as fechaduras 'localidade' como sendo entre os mais sustentou para bloqueios em meu sistema do servidor; ele veio como um pouco de surpresa e pode causar-me a rever a abordagem que eu tenho vindo a tomar (ou seja movimento de volta para sprintf de stringstream) ...

stringstream vai fazer ( como xtofl apontou ). formato impulso é uma mais conveniente substituto para snprintf.

Este método não usa correntes nem sprintf. Para além de ter problemas de bloqueio, córregos incorrer em uma sobrecarga de desempenho e é realmente um exagero. Para fluxos a sobrecarga vem da necessidade de construir o tampão de vapor e fluxo. Para sprintf, a sobrecarga vem da necessidade de interpretar a cadeia de formato. Isso funciona mesmo quando n é negativa ou quando a representação de cadeia de n é maior que len . Esta é a solução mais rápida.

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;
}

Existem muitas maneiras de fazer isso. O mais simples seria:

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

sprintf é a C-like maneira de fazer isso, que também funciona em C ++.

C ++, uma combinação de uma saída de corrente de formatação e stringstream (ver http: // www .arachnoid.com / cpptutor / student3.html ) irá fazer o trabalho.

Esta é uma discussão antiga, mas como fmt pode torná-lo para o padrão, aqui é uma solução adicional:

#include <fmt/format.h>

int n = 999;

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

Note que o fmt::format("{:0>6}", n) funciona igualmente bem quando a largura desejada é conhecido em tempo de compilação. Outra opção é rapel :

#include <absl/strings/str_format.h>

int n = 999;

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

Mais uma vez, abs::StrFormat("%06d", n) é possível. formato impulso é outra ferramenta para este problema:

#include <boost/format.hpp>

int n = 999;

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

Infelizmente, largura especificador variável como argumentos acorrentadas com o operador % não são suportados, isso requer uma configuração de string de formato (por exemplo const std::string fmt = "%0" + std::to_string(6) + "d";).

Em termos de desempenho, rapel e reivindicação fmt para ser muito atraente e mais rápido do que impulso. Em qualquer caso, todas as três soluções deve ser mais eficiente do que std::stringstream se aproxima, e que não seja da família std::*printf, eles não sacrificar a segurança de tipo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top