Qual é a maneira mais fácil de converter de int
equivalente string
em C ++. Estou ciente de dois métodos. Existe alguma maneira mais fácil?
(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
c++
string
int
type-conversion
Nemo
fonte
fonte
itoa()
leva três parâmetros.Respostas:
C ++ 11 introduz
std::stoi
(e variantes para cada tipo numérico) estd::to_string
, as contrapartes de Catoi
eitoa
mas expressas em termos destd::string
.é, portanto, a maneira mais curta em que consigo pensar. Você pode até omitir a nomeação do tipo, usando a
auto
palavra-chave:Nota: consulte [string.conversions] ( 21.5 no n3242 )
fonte
to_string
não é membro destd
correção: stackoverflow.com/questions/12975341/...g++ -std=c++11 someFile.cc
std
todos os compiladores que conheço, exceto um.Error : No instance of overloaded function "std::to_string" matches the argument list
eu estou usando VS2010 c ++string s = to_string((_ULonglong)i);
Iniciando uma discussão com o @ v.oddou alguns anos depois, o C ++ 17 finalmente ofereceu uma maneira de executar a solução agnóstica do tipo originalmente baseada em macro (preservada abaixo) sem passar pela feia macro.
Uso:
Resposta original:
Como "converter ... em string" é um problema recorrente, eu sempre defino a macro SSTR () em um cabeçalho central das minhas fontes C ++:
O uso é o mais fácil possível:
O acima é compatível com C ++ 98 (se você não pode usar o C ++ 11
std::to_string
) e não precisa de inclusões de terceiros (se você não pode usar o Boostlexical_cast<>
); essas outras soluções têm um desempenho melhor.fonte
dynamic_cast
mas estou usando o clang para compilar, de modo que se queixe. Se eu simplesmente omitir odynamic_cast
, ele compila bem; que finalidadedynamic_cast
serve nesse caso? Já estamos criando umostringstream
, então por que lançá-lo?ostringstream
, nós o chamamosoperator<<()
, que retornaostream &
- para o qual.str()
não está definido. Eu realmente me pergunto como o clang faria esse trabalho sem o elenco (ou por que ele gera um erro). Esse construto é publicado em muitos lugares e eu o uso há mais de uma década em muitos compiladores diferentes, incluindo MSVC, GCC e XLC, por isso estou surpreso com o fato de ele não gostar.do { } while( 0 )
não adicionaria nada. Com 2. e 3. você provavelmente entendeu - isso pode ser feito com um elenco estático, e talvez um de vocês assistentes de modelos possa criar uma interface "melhor". Mas como eu disse, isso não é de forma alguma uma invenção minha. Olhe ao seu redor, essa macro (macro!) É bastante onipresente. Esse é um caso de POLA em si. Eu posso brincar um pouco com isso para torná-lo mais "simplificado".Eu normalmente uso o seguinte método:
É descrito em detalhes aqui .
fonte
ss
, você precisass.clear()
. Eu vi resultados inesperados sem essa inicialização.clear()
umostringstream
objeto recém-criado .clear()
redefine os sinalizadores de erro / EO e ainda não foi gerada nenhuma condição de erro / EO.NumberToString(23213.123)
produz23213.1
enquantostd::to_string(23213.123)
produz23213.123000
O que acontece lá?Provavelmente, a maneira fácil mais comum envolve essencialmente sua segunda opção em um modelo nomeado
lexical_cast
, como o do Boost , para que seu código fique assim:Um detalhe disso é que ele também suporta outros elencos (por exemplo, na direção oposta também funciona).
Observe também que, embora o Boost lexical_cast tenha começado apenas gravando em um string, e sendo extraído novamente do stream, agora ele tem algumas adições. Primeiro, foram adicionadas especializações para alguns tipos; portanto, para muitos tipos comuns, é substancialmente mais rápido que o uso de um fluxo de string. Segundo, agora ele verifica o resultado; portanto (por exemplo), se você converter de uma string para uma
int
, poderá lançar uma exceção se a string contiver algo que não pode ser convertido em umaint
(por exemplo,1234
teria sucesso, mas123abc
seria) .No C ++ 11, há uma
std::to_string
função sobrecarregada para tipos inteiros, para que você possa usar código como:O padrão define isso como equivalente à conversão com
sprintf
(usando o especificador de conversão que corresponde ao tipo de objeto fornecido, como%d
paraint
), em um buffer de tamanho suficiente e, em seguida, criando umstd::string
conteúdo desse buffer.fonte
Se você tiver o Boost instalado (o que você deve):
fonte
Seria mais fácil usar strings:
Ou faça uma função:
fonte
Não que eu saiba, em C ++ puro. Mas uma pequena modificação do que você mencionou
deve funcionar, e é bem curto.
fonte
itoa()
não é uma função padrão!Você pode usar
std::to_string
disponível no C ++ 11, conforme sugerido por Matthieu M .:Ou, se o desempenho for crítico (por exemplo, se você fizer muitas conversões), poderá usar a
fmt::format_int
partir da biblioteca {fmt} para converter um número inteiro emstd::string
:Ou uma string C:
O último não realiza alocações dinâmicas de memória e é 10 vezes mais rápido que
std::to_string
nos benchmarks Boost Karma. Consulte Conversão rápida de número inteiro para string em C ++ para obter mais detalhes.Observe que ambos são seguros para threads.
Ao contrário
std::to_string
,fmt::format_int
não requer C ++ 11 e funciona com qualquer compilador C ++.Isenção de responsabilidade: sou o autor da biblioteca {fmt}.
fonte
c_str()
retorna um ponteiro para um buffer declarado dentro dafmt::FormatInt
classe - para que o ponteiro retornado seja inválido em o ponto e vírgula - ver também stackoverflow.com/questions/4214153/lifetime-of-temporariesstd::string::c_str()
(portanto, a nomeação). Se você quiser usá-lo fora da expressão completa, construa um objeto.FormatInt f(42);
Você poderá usá-lof.c_str()
sem o risco de ser destruído.sprintf()
é muito bom para conversão de formato. Você pode atribuir a sequência C resultante à sequência C ++, como fez em 1.fonte
NULL
tamanho zero e para obter o tamanho necessário do buffer.snprintf
(observe o prefixo SNP ) esprintf
(observe o prefixo SP ). Você passa o tamanho para o anterior e toma cuidado para não exceder o limite, no entanto, o último desconhece o tamanho do buffer e, portanto, pode exceder.snprintf
variante primeiro e umasprintf
variante depois disso. Como o tamanho do buffer é conhecido até então, a chamadasprintf
se torna totalmente segura.Primeiro incluem:
Segundo, adicione o método:
Use o método como este:
ou
fonte
Usar string para conversão de números é perigoso!
Consulte http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/ onde diz que
operator<<
insere saída formatada.Dependendo da localidade atual, um número inteiro maior que 3 dígitos pode ser convertido em uma sequência de 4 dígitos, adicionando um separador de milhares extra.
Por exemplo,
int = 1000
pode ser convertido em uma string1.001
. Isso poderia fazer com que as operações de comparação não funcionassem.Então, eu recomendo fortemente usar o
std::to_string
caminho. É mais fácil e faz o que você espera.Atualizado (veja os comentários abaixo) :
fonte
std::to_string
usa a localidade atual (consulte en.cppreference.com/w/cpp/string/basic_string/to_string , a seção 'Notas'). Quase todas as ferramentas padrão (de strings parasprintf
, mas tambémsscanf
etc) estão usando a localidade atual. Eu não estava ciente disso até recentemente, quando me bateu forte. Atualmente usando coisas caseiras, não é difícil de fazer.Para o C ++ 98 , existem algumas opções:
boost/lexical_cast
O Boost não faz parte da biblioteca C ++, mas contém muitas extensões úteis da biblioteca.
Quanto ao tempo de execução, a
lexical_cast
operação leva cerca de 80 microssegundos (na minha máquina) na primeira conversão e, em seguida, acelera consideravelmente depois, se for feita de forma redundante.itoa
Isso significa que
gcc
/g++
não é possível compilar o código usandoitoa
.Sem tempo de execução para relatar. Eu não tenho Visual Studio instalado, que é supostamente capaz de compilar
itoa
.sprintf
sprintf
é uma função de biblioteca padrão C que funciona em cadeias C e é uma alternativa perfeitamente válida.O
stdio.h
cabeçalho pode não ser necessário. Quanto ao tempo de execução, asprintf
operação leva cerca de 40 microssegundos (na minha máquina) na primeira conversão e, em seguida, acelera consideravelmente depois, se for feita de forma redundante.stringstream
Essa é a principal maneira da biblioteca C ++ de converter números inteiros em seqüências de caracteres e vice-versa. Existem funções irmãs semelhantes às
stringstream
que limitam ainda mais o uso pretendido do fluxo, comoostringstream
. Usarostringstream
especificamente informa ao leitor do seu código que você pretende apenas usar o<<
operador, essencialmente. Essa função é tudo o que é particularmente necessário para converter um número inteiro em uma string. Veja esta pergunta para uma discussão mais elaborada.Quanto ao tempo de execução, a
ostringstream
operação leva cerca de 71 microssegundos (na minha máquina) e, em seguida, acelera consideravelmente depois se for feita de forma redundante, mas não tanto quanto as funções anteriores .É claro que existem outras opções, e você pode até incluir uma delas em sua própria função, mas isso oferece uma visão analítica de algumas das populares.
fonte
O C ++ 17 fornece std :: to_chars como uma alternativa independente de localidade de alto desempenho.
fonte
É bastante fácil adicionar um pouco de açúcar sintático que permita compor cordas em tempo real de maneira semelhante a um fluxo
Agora você pode anexar o que quiser (desde que um operador
<< (std::ostream& ..)
esteja definido para ele)strmake()
e usá-lo no lugar de umstd::string
.Exemplo:
fonte
EDITADO. Se você precisar de uma conversão rápida de um número inteiro com um número fixo de dígitos para char * preenchido à esquerda com '0' , este é o exemplo para arquiteturas little-endian (todas x86, x86_64 e outras):
Se você estiver convertendo um número de dois dígitos:
Se você estiver convertendo um número de três dígitos:
Se você estiver convertendo um número de quatro dígitos:
E assim por diante, até números de sete dígitos. Neste exemplo
n
é um número inteiro especificado. Após a conversão, a representação da string pode ser acessada como(char*)&s
:NOTA: Se você precisar dele em ordem de bytes big-endian, embora eu não o tenha testado, mas aqui está um exemplo: para números de três dígitos, é
int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8;
para números de quatro dígitos (arco de 64 bits):int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32;
acho que deve funcionar.fonte
Usar:
fonte
Eu uso:
Funciona nos meus compiladores Windows e Linux g ++.
fonte
sprintf
é conhecido por inserir dados em uma sequência do formato necessário.Você pode converter uma
char *
matriz em uma string, como mostrado na terceira linha.fonte
Isso funcionou para mim -
Meu código:
fonte
stringstream
?std::to_string()
using namespace std;
:)C ++ 11 introduzido
std::to_string()
para tipos numéricos:fonte
Usar:
fonte
fonte
Se você estiver usando o MFC , poderá usar
CString
:fonte
fonte
Agora você pode usar
to_string(5)
.fonte
std
espaço para nome também não é algo que você deve fazer. Além disso, não parece_MAX_INT_DIG
ser uma macro padrão; portanto, se for definido incorretamente, esse código terá o grande potencial de induzir um comportamento indefinido. -1Eu acho que usar
stringstream
é bem fácil:fonte
Você usa um tipo de contador de algoritmo para converter em uma string. Eu peguei essa técnica de programação de computadores Commodore 64 . Também é bom para programação de jogos.
Você pega o número inteiro e cada dígito ponderado pelas potências de 10. Portanto, assuma que o número inteiro é 950.
Se o número inteiro for igual ou superior a 100.000, subtraia 100.000 e aumente o contador na string em ["000000"];
continue fazendo isso até que não haja mais números na posição 100.000. Solte outro poder de dez.
Se o número inteiro for igual ou superior a 10.000, subtraia 10.000 e aumente o contador na string na posição ["000000"] + 1;
continue fazendo isso até que não haja mais números na posição 10.000.
Solte outro poder de dez
Sei que o 950 é muito pequeno para ser usado como exemplo, mas espero que você entenda.
fonte