La bonne façon de copier des C-strings
Est-il un moyen facile de copier des C-strings?
J'ai const char *stringA
, et je veux char *stringB
de prendre la valeur (note que stringB
n'est pas const
). J'ai essayé stringB=(char*) stringA
, mais qui fait stringB
pointent toujours vers le même emplacement de mémoire, de sorte que lorsque stringA
modifications ultérieures, stringB
ne trop.
J'ai aussi essayé de strcpy(stringB,stringA)
, mais il me semble que si stringB
n'était pas initialisé à un assez grand tableau, il y a une erreur de segmentation. Je ne suis pas super expérimenté avec C-strings bien, suis-je raté quelque chose d'évident? Si je viens d'initialiser stringB
comme char *stringB[23]
, parce que je sais que je ne serai jamais une chaîne de plus de 22
personnages (et en permettant le terminateur null), est-ce le bon chemin? Si stringB
est vérifiée pour l'égalité avec les autres C-strings, l'espace supplémentaire affecte en rien?
(et seulement à l'aide de cordes n'est pas une solution, car j'ai besoin d'un minimum de frais généraux et d'un accès facile à des caractères individuels)
c = s[10]
et s[10] = c
à la fois le travail tout aussi bien si s
est un std::string
que si c'est une char*
.Veuillez formater votre question. Vous pouvez utiliser des backticks pour désigner code en ligne et retrait en quatre espaces d'avoir des blocs de code.
Utilisation
std::string
sauf si vous avez une autre raison que celle qui ne pas.std::string est la solution. Vous êtes travaillant sous la fausse idée qu'il sera plus cher.
Désolé pour la mise en forme; je n'arrivais pas à comprendre ce que backticks (apostrophes ne semblent pas faire quoi que ce soit).
OriginalL'auteur akroy | 2012-03-06
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser
strdup()
de retourner une copie d'un C-string, comme dans:Vous pouvez également utiliser
strcpy()
, mais vous avez besoin d'allouer de l'espace tout d'abord, ce qui n'est pas dur à faire, mais peut conduire à une erreur de dépassement de capacité, si ne pas fait correctement:Si vous ne pouvez pas utiliser
strdup()
, je vous recommande l'utilisation destrncpy()
au lieu destrcpy()
. Lestrncpy()
fonction copie jusqu'à et seulement jusqu'àn
octets, ce qui permet d'éviter les erreurs de dépassement. Sistrlen(stringA) + 1 > n
, cependant, vous avez besoin de mettre finstringB
, vous-même. Mais, généralement, vous saurez quelles sont les tailles dont vous avez besoin pour les choses:Je pense que
strdup()
est plus propre, moi-même, j'ai donc essayer de l'utiliser là où le travail avec les chaînes exclusivement. Je ne sais pas si il y a de graves inconvénients pour la POSIX/non-POSIX approche, en terme de performance, mais je ne suis pas un C ou C++ expert.Remarque que j'ai jeté le résultat de
malloc()
àchar *
. C'est parce que votre question est étiqueté comme unec++
question. En C++, il est nécessaire de jeter le résultat demalloc()
. En C, cependant, vous pas cast.MODIFIER
Là vous allez, il y a une complication:
strdup()
n'est pas en C ou C++. Donc, utiliserstrcpy()
oustrncp()
avec un tableau de taille ou unmalloc
-ed pointeur. C'est une bonne habitude d'utiliserstrncp()
au lieu destrcpy()
, partout où vous pourriez utiliser cette fonction. Il permettra de réduire la possibilité d'erreurs.strdup
est dans POSIX, pas du C et C++.strdup()
est à peine plus qu'un wrapper pourstrlen()
,malloc
, etmemset
. Je dis, si vous faites cela comme un exercice d'apprentissage, l'utilisationstrlen()
etmemset
de sorte que vous pouvez apprendre comment les choses fonctionnent dans la peur, puissant monde de l'édition directe de la mémoire 🙂Non, ne pas utiliser
strncpy
au lieu destrcpy
.strncpy
a été créé pour l'insertion des chaînes dans d'autres chaînes. Ainsi, il n'est pas null mettre fin à la chaîne. C'est la négociation d'un problème pour un autre de même ampleur.OriginalL'auteur Alex Reynolds
Presque. En C, si vous savez à coup sûr que la chaîne ne sera jamais trop longtemps:
ou, s'il y a une possibilité que la chaîne peut être trop long:
En C++, vous devez utiliser
std::string
, sauf si vous l'avez prouvé que la surcharge est prohibitif. De nombreuses implémentations ont un "court optimisation de la chaîne", ce qui permettra d'éviter l'allocation dynamique de chaînes courtes; dans ce cas, il y aura peu ou pas de frais généraux sur l'aide d'un C-gamme de style. L'accès aux caractères individuels est tout aussi pratique que d'un C-gamme de style; dans les deux cas,s[i]
donne le caractère à la positioni
comme un lvalue. La copie devientstringB = stringA;
aucun risque de comportement indéfini.Si vraiment vous trouvez que
std::string
est inutilisable, envisagerstd::array<char,MAX+1>
: un copiable classe contenant un tableau de taille fixe.Si vous utilisez
strcmp
, puis il s'arrêtera à la fin de la plus courte chaîne, et ne sera pas affecté par l'espace supplémentaire.OriginalL'auteur Mike Seymour
Si vous voulez le faire dans le plus pur style C que:
Si vous voulez le faire (genre de) C++ style:
OriginalL'auteur sirgeorge
Vous êtes probablement à la recherche pour
strncpy
, qui vous permet de copier la premièren
caractères d'une chaîne. Assurez-vous simplement d'ajouter de la valeur null-terminator à la position n du copié-string.OriginalL'auteur Ken Wayne VanderLinde