Como anexar um char a um std :: string?

175

O seguinte falha com o erro prog.cpp:5:13: error: invalid conversion from ‘char’ to ‘const char*’

int main()
{
  char d = 'd';
  std::string y("Hello worl");
  y.append(d); // Line 5 - this fails
  std::cout << y;
  return 0;
}

Eu também tentei, o seguinte, que compila, mas se comporta aleatoriamente em tempo de execução:

int main()
{
  char d[1] = { 'd' };
  std::string y("Hello worl");
  y.append(d);
  std::cout << y;
  return 0;
}

Desculpe por esta pergunta idiota, mas eu pesquisei no google, o que eu pude ver são apenas "char array to char ptr", "char ptr to char array", etc.

afogar-se
fonte
um erro do compilador sim .. esqueci qual é o erro, mas é razoável.
drowneath
3
Você tem respostas melhores abaixo, mas pode fazer o segundo exemplo funcionar assim: char d [2] = {'d', 0}; ou apenas char d [2] = "d"; Basicamente, você precisa de um 0 para terminar sua seqüência c-estilo que você passar para acrescentar
SBK
Boa documentação aqui: sgi.com/tech/stl/basic_string.html
Martin York

Respostas:

224
y += d;

Eu usaria +=operador em vez de funções nomeadas.

AraK
fonte
2
por que você considera + = melhor que push_back? É apenas menos digitação ou você tem outro motivo?
Glen
4
É menos digitado. In gcc, basic_string::operator+=é apenas uma chamada push_back.
eduffy
2
É IMO mais natural para seqüências de caracteres. push_back é função de recipiente, e uma corda é um especializado em STL :)
ARAK
6
Vamos mudar essa questão: por que você considera o push_back melhor que + =? Na minha opinião, + = é claro e conciso.
Jesper
34
Você quer ter cuidado com isso, porque se você adquirir o hábito, isso será compilado se yfor um em char*vez de std::string. Adicionaria dcaracteres ao ponteiro y.
Zan Lynx
65

Use push_back():

std::string y("Hello worl");
y.push_back('d')
std::cout << y;
Ferdinand Beyer
fonte
19

Para adicionar um caractere a um std :: string var usando o método append, você precisa usar esta sobrecarga:

std::string::append(size_type _Count, char _Ch)

Edit: Você está certo Eu entendi errado o parâmetro size_type, exibido na ajuda de contexto. Este é o número de caracteres a serem adicionados. Portanto, a chamada correta é

s.append(1, d);

não

s.append(sizeof(char), d);

Ou a maneira mais simples:

s += d;
Patrice Bernassola
fonte
Eu acho que usar sizeof não é semanticamente correto aqui (mesmo que funcione como sizeof (char) é sempre um). O método de acréscimo é naturalmente mais útil se você quiser acrescentar mais cópias do mesmo caractere !!!!!!!!!!
UncleBens 24/09/09
1
Por que você está usando em sizeof(char)vez de 1? Você deseja anexar exatamente uma repetição de d, então diga isso. O uso sizeofaqui é enganoso, pois sugere que é preciso informar appendo tamanho de byte do tipo de dados usado (o que não é o caso).
28630 Ferdinand Beyer
Como o Unclebens disse, o método de acréscimo é realmente mais útil ao adicionar o mesmo caractere várias vezes.
Patrice Bernassola
10

Além dos outros mencionados, um dos construtores de string recebe um caractere e o número de repetições para esse caractere. Então você pode usar isso para acrescentar um único caractere.

std::string s = "hell";
s += std::string(1, 'o');
Brian R. Bondy
fonte
7

Testo as várias proposições executando-as em um loop grande. Eu usei o microsoft visual studio 2015 como compilador e meu processador é um i7, 8Hz, 2GHz.

    long start = clock();
    int a = 0;
    //100000000
    std::string ret;
    for (int i = 0; i < 60000000; i++)
    {
        ret.append(1, ' ');
        //ret += ' ';
        //ret.push_back(' ');
        //ret.insert(ret.end(), 1, ' ');
        //ret.resize(ret.size() + 1, ' ');
    }
    long stop = clock();
    long test = stop - start;
    return 0;

De acordo com este teste, os resultados são:

     operation             time(ms)            note
------------------------------------------------------------------------
append                     66015
+=                         67328      1.02 time slower than 'append'
resize                     83867      1.27 time slower than 'append'
push_back & insert         90000      more than 1.36 time slower than 'append'

Conclusão

+= parece mais compreensível, mas se você se importa com velocidade, use

Hugo Zevetel
fonte
Para que essa resposta seja significativa, você deve dizer ao menos qual compilador está usando, porque essas coisas podem variar MUITO. Contar sobre o seu processador também pode ser ótimo, para obter uma estimativa aproximada do impacto real que isso pode ter.
akaltar
Eu usei o visual studio 2015. Vou procurar pelo gcc para fazer outros testes. Meu processador é i7, 8 corações, 2,20 Ghz .... Mas, seja qual for o meu processador, não terá impacto na implementação de std :: string ... exceto se alguns desses métodos forem multithread e outros não.
Hugo Zevetel 01/09/16
Às vezes, isso tem um impacto, especialmente se você estiver mostrando tempos em milissegundos. Em vez disso, você pode mostrar em porcentagem em relação ao método mais rápido (portanto, a velocidade real do processador é irrelevante) Mova esses dados do comentário para sua resposta, isso é apenas uma etiqueta geral do StackExchange. Caso contrário, boa resposta.
akaltar 01/09/16
6

Experimente o operador + = texto do link , append () Método texto do link , ou push_back () Método texto do link

Os links nesta postagem também contêm exemplos de como usar as respectivas APIs.

Michael Berg
fonte
2

o problema com:

std::string y("Hello worl");
y.push_back('d')
std::cout << y;

é que você precisa ter o 'd' em vez de usar o nome de um caractere, como char d = 'd'; Ou eu estou errado?

Alex Spencer
fonte
Eu apenas tentei e funcionou bem. Eu tenho char c = 'd'e posso fazer y.push_back(c)sem problemas. Portanto, não há nenhum problema com std::string::push_back()(exceto que é mais longo que +=).
Franklin Yu
1
int main()
{
  char d = 'd';
  std::string y("Hello worl");

  y += d;
  y.push_back(d);
  y.append(1, d); //appending the character 1 time
  y.insert(y.end(), 1, d); //appending the character 1 time
  y.resize(y.size()+1, d); //appending the character 1 time
  y += std::string(1, d); //appending the character 1 time
}

Note-se que em todos esses exemplos você poderia ter usado um literal de caracteres diretamente: y += 'd';.

Seu segundo exemplo quase teria funcionado, por razões não relacionadas. char d[1] = { 'd'};fez não trabalho, mas char d[2] = { 'd'};(nota a matriz é tamanho dois) teria sido trabalhado aproximadamente o mesmo que const char* d = "d";e um literal de cadeia pode ser anexada: y.append(d);.

Mooing Duck
fonte
1

Tente usar d como ponteiro y.append (* d)

2ndless
fonte
Isso é perigoso, pois um único charnão é uma string e não tem um terminador nulo. Fazer isso causa comportamento indefinido.
Simon Kraemer
Isso está errado. *dsignifica desassociar o ponteiro, dque é um erro de sintaxe, pois dnão é um ponteiro.
Franklin Yu
0
str.append(10u,'d'); //appends character d 10 times

Observe que escrevi 10u e não 10 para o número de vezes que gostaria de acrescentar o personagem; substitua 10 por qualquer número.

Ioan Stef
fonte
0

Eu encontrei uma maneira simples ... Eu precisava prender charuma corda que estava sendo construída rapidamente. Eu precisava de um char list;porque estava dando ao usuário uma escolha e usando essa opção em uma switch()declaração.

Simplesmente adicionei outra std::string Slist;e defina a nova string igual ao caractere "list" - a, b, c ou o que o usuário final escolher assim:

char list;
std::string cmd, state[], Slist;
Slist = list; //set this string to the chosen char;
cmd = Slist + state[x] + "whatever";
system(cmd.c_str());

A complexidade pode ser fria, mas a simplicidade é mais fria. Na minha humilde opinião

Charles H
fonte
0

Também adicionando a opção de inserção, como ainda não mencionado.

std::string str("Hello World");
char ch;

str.push_back(ch);  //ch is the character to be added
OR
str.append(sizeof(ch),ch);
OR
str.insert(str.length(),sizeof(ch),ch) //not mentioned above
Gopesh Bharadwaj
fonte
-1

Se você estiver usando o push_back, não há chamada para o construtor de cadeias. Caso contrário, ele criará um objeto de string por meio de conversão e, em seguida, adicionará o caractere nessa string à outra string. Muitos problemas para um personagem minúsculo;)

progician
fonte
1
operador + = (caractere c); está sobrecarregado para seqüências de caracteres. De fato, o construtor de strings não aceita um caractere, veja a resposta de Brian;)
AraK