Come aggiungere un carattere a uno std :: string?


175

Quanto segue non riesce con l'errore 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;
}

Ho anche provato, il seguente, che compila ma si comporta in modo casuale in fase di esecuzione:

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

Ci scusiamo per questa domanda stupida, ma ho cercato su Google, quello che ho potuto vedere sono solo "char array to char ptr", "char ptr to char array", ecc.


un errore del compilatore sì..ho dimenticato qual è l'errore, ma è ragionevole.
annegamento il

3
Di seguito troverai le risposte migliori, ma puoi fare in modo che il tuo secondo esempio funzioni in questo modo d [2] = {'d', 0}; o semplicemente char d [2] = "d"; Fondamentalmente, hai bisogno di uno 0 per terminare la stringa di tipo c che passi per aggiungere
sbk,

Risposte:


225
y += d;

Vorrei utilizzare l' +=operatore anziché le funzioni con nome.


2
perché consideri + = meglio di push_back? Scrive meno o hai un altro motivo?
Glen,

4
Scrive meno. In gcc, basic_string::operator+=è solo una chiamata push_back.
spigoloso

2
È l'IMO più naturale per le stringhe. push_back è una funzione contenitore e una stringa è specializzata in STL :)
AraK,

6
Rivolgiamoci a questa domanda: perché consideri push_back migliore di + =? Secondo me, + = è chiaro e conciso.
Jesper,

34
Vuoi stare attento con questo perché se prendi l'abitudine, questo si compila bene se yè un char*invece di std::string. Aggiungerebbe dcaratteri al puntatore y.
Zan Lynx,

65

Utilizzare push_back():

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

19

Per aggiungere un carattere a un var std :: string utilizzando il metodo append, è necessario utilizzare questo sovraccarico:

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

Modifica: hai ragione, ho frainteso il parametro size_type, visualizzato nella guida contestuale. Questo è il numero di caratteri da aggiungere. Quindi la chiamata corretta è

s.append(1, d);

non

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

O il modo più semplice:

s += d;

Penso che usare sizeof non sia semanticamente corretto qui (anche se succede che sizeof (char) è sempre uno). Il metodo append è naturalmente più utile se vuoi aggiungere più copie dello stesso personaggio !!!!!!!!!!
UncleBens,

1
Perché stai usando sizeof(char)invece di 1? Volete aggiungere esattamente una ripetizione di d, quindi ditelo. L'uso sizeofqui è fuorviante poiché suggerisce che si deve dire appendla dimensione in byte del tipo di dati utilizzato (che non è il caso).
Ferdinand Beyer,

Come diceva Unclebens, il metodo append è molto più utile quando si aggiunge lo stesso personaggio più volte.
Patrice Bernassola,

10

Oltre agli altri citati, uno dei costruttori di stringhe prende un carattere e il numero di ripetizioni per quel carattere. Quindi puoi usarlo per aggiungere un singolo carattere.

std::string s = "hell";
s += std::string(1, 'o');

7

Metto alla prova le varie proposizioni eseguendole in un grande ciclo. Ho usato Microsoft Visual Studio 2015 come compilatore e il mio processore è un 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;

Secondo questo test, i risultati sono:

     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'

Conclusione

+= sembra più comprensibile, ma se ti preoccupi della velocità, usa append


Affinché una tale risposta sia significativa, dovresti almeno dire quale compilatore stai usando, perché tali cose potrebbero variare molto. Anche parlare del tuo processore può essere fantastico, per ottenere una stima approssimativa dell'impatto reale che questo potrebbe avere.
Akaltar

Ho usato Visual Studio 2015. Cercherò gcc per fare altri test. Il mio processore è i7, 8 cuori, 2,20 Ghz .... Ma qualunque sia il mio processore non avrà alcun impatto sull'implementazione di std :: string ... tranne se alcuni di questi metodi sono multithread e altri no.
Hugo Zevetel,

A volte ha un impatto, soprattutto se stai visualizzando i tempi in millisecondi. Invece potresti mostrare in percentuale rispetto al metodo più veloce (quindi la velocità effettiva del processore è irrilevante). Sposta anche quei dati dal commento alla tua risposta, questa è solo etichetta generale StackExchange. Altrimenti bella risposta.
Akaltar


2

il problema con:

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

è che devi avere la 'd' invece di usare il nome di un carattere, come char d = 'd'; O mi sbaglio?


L'ho appena provato e ha funzionato bene. Ho char c = 'd'e posso fare a y.push_back(c)meno. Quindi non ci sono problemi con std::string::push_back()(tranne che è più lungo di +=).
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
}

Si noti che in tutti questi esempi si potrebbe avere utilizzato direttamente un letterale carattere: y += 'd';.

Il tuo secondo esempio avrebbe quasi funzionato, per ragioni non correlate. char d[1] = { 'd'};non ha funzionato, ma char d[2] = { 'd'};(nota la matrice è formato due) sarebbero stati lavorati o meno lo stesso const char* d = "d";, ed un letterale stringa può essere aggiunto: y.append(d);.


1

Prova a usare la d come puntatore y.append (* d)


È pericoloso poiché un singolo charnon è una stringa e non ha un terminatore null. Ciò causa un comportamento indefinito.
Simon Kraemer,

Questo è semplicemente sbagliato. *dsignifica puntatore di de-riferimento dche è un errore di sintassi poiché dnon è un puntatore.
Franklin Yu,

0
str.append(10u,'d'); //appends character d 10 times

Nota che ho scritto 10u e non 10 per il numero di volte in cui vorrei aggiungere il personaggio; sostituire 10 con qualunque numero.


0

Ho trovato un modo semplice ... Avevo bisogno di attaccare charuna corda che veniva costruita al volo. Avevo bisogno di un char list;perché stavo dando all'utente una scelta e usando quella scelta in una switch()dichiarazione.

Ho semplicemente aggiunto un altro std::string Slist;e ho impostato la nuova stringa uguale al carattere, "elenco" - a, b, c o qualsiasi altra cosa l'utente finale scelga in questo modo:

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());

La complessità può essere interessante, ma la semplicità è più interessante. A parer mio


0

Aggiunta anche dell'opzione di inserimento, come non ancora menzionato.

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

-1

Se si utilizza push_back, non è disponibile alcuna chiamata per il costruttore di stringhe. Altrimenti creerà un oggetto stringa tramite casting, quindi aggiungerà il carattere in questa stringa all'altra stringa. Troppi problemi per un personaggio minuscolo;)


1
operatore + = (carattere c); è sovraccarico per le stringhe. In effetti, il costruttore di stringhe non accetta un carattere, vedi la risposta di Brian;)
AraK,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.