Comment ajouter un caractère à une chaîne std :: string?


175

Ce qui suit échoue avec l'erreur 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;
}

J'ai également essayé ce qui suit, qui compile mais se comporte de manière aléatoire au moment de l'exécution:

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

Désolé pour cette question stupide, mais j'ai cherché dans google, ce que je pouvais voir sont juste "char array to char ptr", "char ptr to char array", etc.


une erreur du compilateur oui..J'ai oublié quelle est l'erreur, mais c'est raisonnable.
noyade le

3
Vous avez de meilleures réponses ci-dessous, mais vous pouvez faire de votre deuxième exemple fonctionnant comme ceci char d [2] = {'d', 0}; ou simplement char d [2] = "d"; Fondamentalement, vous avez besoin d'un 0 pour terminer votre chaîne de style c que vous passez à ajouter
sbk

Réponses:


225
y += d;

J'utiliserais un +=opérateur au lieu de fonctions nommées.


2
pourquoi considérez-vous + = mieux que push_back? Est-ce simplement moins de frappe ou avez-vous une autre raison?
Glen

4
C'est moins tapant. In gcc, basic_string::operator+=est juste un appel push_back.
eduffy

2
Il est plus naturel IMO pour les cordes. push_back est une fonction de conteneur, et une chaîne est une fonction spécialisée dans STL :)
AraK

6
Retournons cette question: pourquoi considérez-vous push_back mieux que + =? À mon avis, + = est clair et concis.
Jesper

34
Vous devez être prudent avec cela car si vous en prenez l'habitude, cela se compilera très bien si yc'est un char*au lieu de std::string. Cela ajouterait des dcaractères au pointeur y.
Zan Lynx

65

Utilisez push_back():

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

19

Pour ajouter un caractère à un var std :: string à l'aide de la méthode append, vous devez utiliser cette surcharge:

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

Edit: Vous avez raison, j'ai mal compris le paramètre size_type, affiché dans l'aide contextuelle. Il s'agit du nombre de caractères à ajouter. Donc le bon appel est

s.append(1, d);

ne pas

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

Ou de la manière la plus simple:

s += d;

Je pense que l'utilisation de sizeof n'est pas sémantiquement correcte ici (même si cela fonctionne car sizeof (char) est toujours un). La méthode append est naturellement plus utile si vous souhaitez ajouter plus de copies du même caractère !!!!!!!!!!
UncleBens

1
Pourquoi utilisez-vous sizeof(char)au lieu de 1? Vous voulez ajouter exactement une répétition de d, alors dites-le simplement. L'utilisation sizeofici est trompeuse car elle suggère que l'on doit indiquer appendla taille en octets du type de données utilisé (ce qui n'est pas le cas).
Ferdinand Beyer

Comme l'a dit Unclebens, la méthode append est vraiment plus utile lors de l'ajout du même caractère plusieurs fois.
Patrice Bernassola

10

En plus des autres mentionnés, l'un des constructeurs de chaînes prend un char et le nombre de répétitions pour ce char. Vous pouvez donc l'utiliser pour ajouter un seul caractère.

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

7

Je teste les différentes propositions en les exécutant dans une grande boucle. J'ai utilisé Microsoft Visual Studio 2015 comme compilateur et mon processeur est 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;

Selon ce test, les résultats sont:

     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'

Conclusion

+= semble plus compréhensible, mais si la vitesse vous préoccupe, utilisez append


Pour qu'une telle réponse soit significative, vous devriez au moins dire quel compilateur vous utilisez, car de telles choses peuvent varier beaucoup. Parler de votre processeur peut également être très utile, pour obtenir une estimation approximative de l'impact réel que cela pourrait avoir.
akaltar

J'ai utilisé visual studio 2015. Je chercherai gcc pour faire d'autres tests. Mon processeur est i7, 8 coeurs, 2,20 Ghz .... Mais quel que soit mon processeur il n'aura aucun impact sur l'implémentation std :: string ... sauf si certaines de ces méthodes sont multithread et d'autres non.
Hugo Zevetel

Parfois, cela a un impact, surtout si vous affichez les durées en millisecondes. Au lieu de cela, vous pouvez afficher en pourcentage par rapport à la méthode la plus rapide (la vitesse réelle du processeur n'est donc pas pertinente). Déplacez également ces données du commentaire vers votre réponse, il ne s'agit que de l'étiquette générale de StackExchange. Sinon belle réponse.
akaltar le


2

le problème avec:

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

est que vous devez avoir le 'd' par opposition à l'utilisation d'un nom de caractère, comme char d = 'd'; Ou ai-je tort?


Je viens de l'essayer et cela a bien fonctionné. J'ai char c = 'd'et je peux le faire y.push_back(c)sans problème. Il n'y a donc pas de problème avec std::string::push_back()(sauf que c'est plus long 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
}

Notez que dans tous ces exemples que vous auriez pu utiliser un littéral de caractère directement: y += 'd';.

Votre deuxième exemple aurait presque fonctionné, pour des raisons indépendantes. char d[1] = { 'd'};n'a pas fonctionné, mais char d[2] = { 'd'};(note du tableau est de taille deux) aurait été travaillé à peu près la même que const char* d = "d";, et un littéral de chaîne peut être jointe: y.append(d);.


1

Essayez d'utiliser le d comme pointeur y.append (* d)


C'est dangereux car un single charn'est pas une chaîne et n'a pas de terminateur nul. Cela provoque un comportement indéfini.
Simon Kraemer le

C'est tout simplement faux. *dsignifie un pointeur de dé-référence dqui est une erreur de syntaxe car dn'est pas un pointeur.
Franklin Yu

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

Remarquez que j'ai écrit 10u et non 10 pour le nombre de fois où j'aimerais ajouter le caractère; remplacez 10 par n'importe quel nombre.


0

J'ai trouvé un moyen simple ... J'avais besoin de clouer un charsur une corde qui était construite à la volée. J'avais besoin d'un char list;car je donnais un choix à l'utilisateur et en utilisant ce choix dans unswitch() déclaration.

J'ai simplement ajouté une autre std::string Slist;et défini la nouvelle chaîne égale au caractère, "liste" - a, b, c ou tout ce que l'utilisateur final choisit comme ceci:

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 complexité peut être cool mais la simplicité est plus cool. A mon humble avis


0

Ajout également une option d'insertion, comme pas encore mentionné.

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

Si vous utilisez le push_back, il n'y a pas d'appel pour le constructeur de chaîne. Sinon, il créera un objet chaîne via la conversion, puis il ajoutera le caractère de cette chaîne à l'autre chaîne. Trop de problèmes pour un petit personnage;)


1
opérateur + = (car c); est surchargé pour les chaînes. En fait, le constructeur de chaîne n'accepte pas un caractère, voir la réponse de Brian;)
AraK
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.