Eu tenho um vector<int>
contêiner que tem números inteiros (por exemplo, {1,2,3,4}) e gostaria de converter para uma string da forma
"1,2,3,4"
Qual é a maneira mais limpa de fazer isso em C ++? Em Python, eu faria isso:
>>> array = [1,2,3,4]
>>> ",".join(map(str,array))
'1,2,3,4'
Respostas:
Definitivamente, não é tão elegante quanto Python, mas nada é tão elegante quanto Python em C ++.
Você poderia usar um
stringstream
...Você também pode usar em
std::for_each
vez disso.fonte
std::string s = ss.str()
. Se você quiser umconst char*
, uses.c_str()
. (Observe que, embora sintaticamente correto,ss.str().c_str()
dará a você umconst char*
que aponta para um temporário que deixará de existir no final da expressão completa. Isso dói.)#include <sstream>
Usando std :: for_each e lambda você pode fazer algo interessante.
Veja esta pergunta para uma pequena aula que escrevi. Isso não imprimirá a vírgula final. Além disso, se assumirmos que o C ++ 14 continuará a nos fornecer equivalentes baseados em intervalo de algoritmos como este:
fonte
Você pode usar std :: acumular. Considere o seguinte exemplo
fonte
','
deveria ser","
string
classe tem uma sobrecarga para o+
operador que também pode aceitar caracteres. Então','
está tudo bem.Outra alternativa é o uso de
std::copy
e daostream_iterator
classe:Também não é tão bom quanto Python. Para isso, criei uma
join
função:Então usei assim:
Você pode perguntar por que passei nos iteradores. Bem, na verdade, eu queria inverter a matriz, então usei assim:
Idealmente, eu gostaria de modelar até o ponto em que pudesse inferir o tipo char e usar string-streams, mas ainda não consegui descobrir isso.
fonte
join
função pode ser usada com vetores também? Você pode dar um exemplo, eu sou novo em C ++.Com Boost e C ++ 11, isso pode ser feito assim:
Bem, quase. Aqui está o exemplo completo:
Crédito para Pretoriano .
Você pode lidar com qualquer tipo de valor como este:
fonte
Esta é apenas uma tentativa de resolver o enigma dado pela observação de 1800 INFORMAÇÕES sobre sua segunda solução carente de genericidade, não uma tentativa de responder à pergunta:
Funciona na minha máquina (TM).
fonte
operator<<
sobrecarregado). Obviamente, um tipo semoperator<<
pode causar mensagens de erro muito confusas.join(v.begin(), v.end(), ",")
. A dedução do argumento do modelo não produz o resultado correto se osep
argumento for um literal de string. Minha tentativa de uma solução para este problema . Também oferece uma sobrecarga baseada em alcance mais moderna.Muitos modelos / ideias. O meu não é tão genérico ou eficiente, mas eu simplesmente tive o mesmo problema e queria jogar isso na mistura como algo curto e doce. Ele vence no menor número de linhas ... :)
fonte
substr(...)
, usepop_back()
para remover o último caractere, torna-se muito mais claro e limpo então.Se quiser fazer
std::cout << join(myVector, ",") << std::endl;
, você pode fazer algo como:Observe que esta solução faz a junção diretamente no fluxo de saída em vez de criar um buffer secundário e funcionará com qualquer tipo que tenha um operador << em um ostream.
Isso também funciona onde
boost::algorithm::join()
falha, quando você tem um emvector<char*>
vez de umvector<string>
.fonte
fonte
std::stringstream
para grandes arrays porquestringstream
será capaz de alocar memória de forma otimista, levando a desempenho O (n.log (n)) em vez de O (n²) para um array de tamanhon
para esta resposta. Tambémstringstream
não pode construir strings temporárias parato_string(i)
.Gosto da resposta de 1800. No entanto, eu moveria a primeira iteração para fora do loop, pois o resultado da instrução if só muda uma vez após a primeira iteração
É claro que isso pode ser reduzido a menos declarações, se você quiser:
fonte
++i
exceto onde realmente precisassem,i++
porque essa era a única maneira de eles não se esquecerem disso quando fizesse a diferença. (Foi o mesmo comigo, BTW.) Eles tinham aprendido Java antes, onde todos os tipos de C-ismos estão em voga e levaram alguns meses (1 aula + trabalho de laboratório por semana), mas no final a maior parte eles aprenderam o hábito de usar o pré-incremento.Existem algumas tentativas interessantes de fornecer uma solução elegante para o problema. Tive a ideia de usar fluxos de modelo para responder com eficácia ao dilema original do OP. Embora esta seja uma postagem antiga, espero que os futuros usuários que encontrarem isso achem minha solução benéfica.
Primeiro, algumas respostas (incluindo a resposta aceita) não promovem a reutilização. Uma vez que C ++ não fornece uma maneira elegante de juntar strings na biblioteca padrão (que eu vi), torna-se importante criar uma que seja flexível e reutilizável. Aqui está minha chance:
Agora, para usar isso, você pode simplesmente fazer algo como o seguinte:
Observe como o uso de streams torna esta solução incrivelmente flexível, pois podemos armazenar nosso resultado em um stringstream para recuperá-lo mais tarde, ou podemos gravar diretamente na saída padrão, um arquivo ou mesmo em uma conexão de rede implementada como um stream. O tipo que está sendo impresso deve ser simplesmente iterável e compatível com o fluxo de origem. O STL fornece vários fluxos compatíveis com uma grande variedade de tipos. Então você poderia realmente ir para a cidade com isso. No topo da minha cabeça, seu vetor pode ser int, float, double, string, unsigned int, SomeObject * e muito mais.
fonte
Criei um arquivo de cabeçalho auxiliar para adicionar um suporte estendido de junção.
Basta adicionar o código abaixo ao seu arquivo de cabeçalho geral e incluí-lo quando necessário.
Exemplos de uso:
O código por trás da cena:
fonte
Aqui está uma solução genérica C ++ 11 que permitirá que você faça
O código é:
fonte
O seguinte é uma maneira simples e prática para converter elementos em um
vector
a umstring
:Você precisa
#include <sstream>
paraostringstream
.fonte
Expandindo a tentativa de @sbi em uma solução genérica que não está restrita a
std::vector<int>
um tipo específico de string de retorno. O código apresentado a seguir pode ser usado assim:No código original, a dedução do argumento do modelo não funciona para produzir o tipo de string de retorno correto se o separador for um literal de string (como nos exemplos acima). Neste caso, os typedefs como
Str::value_type
no corpo da função estão incorretos. O código assume queStr
é sempre um tipo semelhantestd::basic_string
, portanto, obviamente falha para literais de string.Para corrigir isso, o código a seguir tenta deduzir apenas o tipo de caractere do argumento separador e usa isso para produzir um tipo de string de retorno padrão. Isso é obtido usando
boost::range_value
, que extrai o tipo de elemento do tipo de intervalo fornecido .Agora podemos facilmente fornecer uma sobrecarga baseada em intervalo que simplesmente encaminha para a sobrecarga baseada em iterador:
Demonstração ao vivo no Coliru
fonte
como @capone fez,
Então podemos chamar o seguinte:
assim como python:
fonte
Eu uso algo assim
fonte
Comecei com a resposta de @sbi, mas na maioria das vezes acabei canalizando a string resultante para um stream, então criei a solução abaixo que pode ser canalizada para um stream sem a sobrecarga de criar a string completa na memória.
É usado da seguinte forma:
Onde string_join.h é:
fonte
Eu escrevi o seguinte código. É baseado em C # string.join. Funciona com std :: string e std :: wstring e muitos tipos de vetores. (exemplos em comentários)
Chame assim:
Código:
fonte
Esta é uma maneira fácil de converter um vetor de inteiros em strings.
fonte
junte-se usando a função de modelo
Usei a
template
function
para juntar osvector
itens e removi aif
instrução desnecessária iterando apenas do primeiro ao penúltimo item no evector
, em seguida, juntando o último item após ofor
loop. Isso também elimina a necessidade de código extra para remover o separador extra no final da string unida. Portanto, nenhumaif
instrução retardando a iteração e nenhum separador supérfluo que precise ser arrumado.Isso produz uma chamada de função elegante para participar de um
vector
dosstring
,integer
oudouble
, etc.Escrevi duas versões: uma retorna uma string; o outro grava diretamente em um fluxo.
Resultado
fonte