O C # possui um recurso de sintaxe onde você pode concatenar vários tipos de dados juntos em uma linha.
string s = new String();
s += "Hello world, " + myInt + niceToSeeYouString;
s += someChar1 + interestingDecimal + someChar2;
Qual seria o equivalente em C ++? Tanto quanto eu posso ver, você teria que fazer tudo em linhas separadas, pois não suporta várias cadeias / variáveis com o operador +. Tudo bem, mas não parece tão legal.
string s;
s += "Hello world, " + "nice to see you, " + "or not.";
O código acima produz um erro.
c++
string
compiler-errors
concatenation
Nick Bolton
fonte
fonte
char *
ponteiros entre si. É isso que gera o erro - porque somar indicadores não faz sentido. Como observado abaixo, transforme pelo menos o 1º operando em umstd::string
e não haverá nenhum erro.Respostas:
Dê uma olhada neste artigo do Guru da Semana de Herb Sutter: Os Formadores de Cordas da Manor Farm
fonte
std::string s = static_cast<std::ostringstream&>(std::ostringstream().seekp(0) << "HelloWorld" << myInt << niceToSeeYouString).str();
std::stringstream ss; ss << "Hello, world, " << myInt << niceToSeeYouString; std::string s = ss.str();
é praticamente uma linhaEm 5 anos ninguém mencionou
.append
?fonte
s.append("One"); s.append(" line");
s.append("One").append(" expression");
Talvez eu deva editar o original para usar o valor de retorno dessa maneira?s
em uma linha diferente no código C # equivalente e em seu código C ++ não compilável. Seu C ++ desejado é os += "Hello world, " + "nice to see you, " + "or not.";
que pode ser escrito #s.append("Hello world, ").append("nice to see you, ").append("or not.");
append
disso é que ele também funciona quando as seqüências contêm caracteres NUL.Esses literais da matriz de caracteres não são C ++ std :: strings - você precisa convertê-los:
Para converter ints (ou qualquer outro tipo de streamable), você pode usar um impulso lexical_cast ou fornecer sua própria função:
Agora você pode dizer coisas como:
fonte
string("Hello world")
são executadasoperator+()
conforme definido na classestring
. Se não houverstring
objeto na expressão, a concatenação se tornará uma mera soma de ponteiros de caractereschar*
.Seu código pode ser escrito como 1 ,
... mas duvido que seja isso que você está procurando. No seu caso, você provavelmente está procurando fluxos:
1 " pode ser escrito como ": isso funciona apenas para literais de string. A concatenação é feita pelo compilador.
fonte
const char smthg[] = "smthg"
: / É um bug?#define
usar sua string para contornar isso, embora isso traga seus próprios problemas.Usando literais definidos pelo usuário C ++ 14 e
std::to_string
o código se torna mais fácil.Observe que a concatenação de literais de string pode ser feita em tempo de compilação. Basta remover o
+
.fonte
std::literals::string_literals
, não ao conceito de UDL.Para oferecer uma solução com mais de uma linha: É
concat
possível implementar uma função para reduzir a solução baseada em cadeia de caracteres "clássica" a uma única instrução . Baseia-se em modelos variados e encaminhamento perfeito.Uso:
Implementação:
fonte
No C ++ 20, você poderá:
Até então, você poderia fazer o mesmo com a biblioteca {fmt} :
Isenção de responsabilidade : sou o autor de {fmt}.
fonte
boost :: format
ou std :: stringstream
fonte
O problema real era que concatenar literais de string com
+
falhas em C ++:No C ++ (também em C), você concatena literais de strings apenas colocando-os um ao lado do outro:
Isso faz sentido, se você gerar código em macros:
... uma macro simples que pode ser usada assim
( demonstração ao vivo ... )
ou, se você insistir em usar os
+
literais de string for (como já sugerido por underscore_d ):Outra solução combina uma sequência e uma
const char*
para cada etapa da concatenaçãofonte
sprintf
é claro, é uma opção, mas também existe std :: stringstream que evita problemas com buffers de tamanho menor.fonte
Você precisaria definir o operador + () para todos os tipos de dados que você gostaria de concenatar com a string, mas como o operador << é definido para a maioria dos tipos, você deve usar std :: stringstream.
Droga, bata em 50 segundos ...
fonte
std::string operator+(std::string s, int i){ return s+std::to_string(i); }
Se você escrever o
+=
, parece quase o mesmo que C #fonte
Como outros disseram, o principal problema com o código OP é que o operador
+
não concatenaconst char *
; funciona comstd::string
, no entanto.Aqui está outra solução que usa lambdas C ++ 11
for_each
e permite fornecer umseparator
para separar as strings:Uso:
Parece escalar bem (linearmente), pelo menos depois de um teste rápido no meu computador; aqui está um teste rápido que eu escrevi:
Resultados (milissegundos):
fonte
Talvez você goste da minha solução "Streamer" para realmente fazer isso em uma linha:
fonte
Aqui está a solução de uma linha:
Embora seja um pouco feio, acho que é o mais limpo que você consegue em C ++.
Estamos lançando o primeiro argumento para a
std::string
e, em seguida, usando a ordem de avaliação (da esquerda para a direita) deoperator+
para garantir que seu operando esquerdo seja sempre astd::string
. Dessa maneira, concatenamos ostd::string
da esquerda com oconst char *
operando do lado direito e retornamos outrostd::string
, fazendo o efeito cascata.Nota: existem algumas opções para o operando direito, incluindo
const char *
,std::string
echar
.Cabe a você decidir se o número mágico é 13 ou 6227020800.
fonte
Você pode usar este cabeçalho para esse assunto: https://github.com/theypsilon/concat
Sob o capô, você usará um std :: ostringstream.
fonte
Se você estiver disposto a usar,
c++11
poderá utilizar literais de string definidos pelo usuário e definir dois modelos de função que sobrecarregam o operador plus de umstd::string
objeto e qualquer outro objeto. A única armadilha é não sobrecarregar os operadores plusstd::string
, caso contrário, o compilador não sabe qual operador usar. Você pode fazer isso usando o modelostd::enable_if
detype_traits
. Depois disso, as strings se comportam como em Java ou C #. Veja meu exemplo de implementação para obter detalhes.Código principal
Arquivo c_sharp_strings.hpp
Inclua esse arquivo de cabeçalho em todos os lugares em que você deseja ter essas strings.
fonte
Algo assim funciona para mim
fonte
Com base nas soluções acima, criei uma classe var_string para o meu projeto para facilitar a vida. Exemplos:
A classe em si:
Ainda querendo saber se haverá algo melhor em C ++?
fonte
Em c11:
isso permite que você crie uma chamada de função como esta:
imprimirá: número da mensagem: 10
fonte
você também pode "estender" a classe de string e escolher o operador de sua preferência (<<, &, |, etc ...)
Aqui está o código usando o operador << para mostrar que não há conflito com fluxos
nota: se você descomentar s1.reserve (30), há apenas 3 novas solicitações de operador () (1 para s1, 1 para s2, 1 para reserva; infelizmente não é possível reservar no tempo do construtor); sem reserva, o s1 precisa solicitar mais memória à medida que cresce, portanto depende do fator de crescimento da implementação do compilador (o meu parece ser 1,5, 5 novas chamadas () neste exemplo)
fonte
Stringstream com uma macro simples de pré-processador usando uma função lambda parece bom:
e depois
fonte
Isso funciona para mim:
Resultado:
fonte
const
ou (se o armazenamento zero for um requisito)enum
seria?Você já tentou evitar o + =? em vez disso, use var = var + ... funcionou para mim.
fonte
#include <iostream.h> // string
#include <system.hpp> // ansiString