7
votes

Obtenez un seul caractère d'un char * en c

Y a-t-il un moyen de traverser le caractère par caractère ou d'extraire un seul caractère de Char * en C?

Considérez le code suivant. Maintenant quel est le meilleur moyen d'obtenir des personnages individuels? Suggérez-moi une méthode sans utiliser de fonctions de chaîne. xxx


0 commentaires

5 Réponses :


4
votes
size_t i;
for (i=0; a[i]; i++) {
    /* do something with a[i] */
}

0 commentaires

2
votes
int i=0;
while(a[i]!=0)/* or a[i]!='\0' */
{
   // do something to a[i]
   ++i;
}
EDIT:You can also use strlen(a) to get the number of characters in a.

3 commentaires

Cela ne serait-il pas si en boucle de sortir des limites?


Non, mais comme c'était, cela n'aurait pas dépassé le personnage de Zeroth. Édité pour inclure ++ i maintenant.


Et cela ne va toujours pas sortir des limites parce que c chaînes sont nuls terminés.



5
votes

Connaître la longueur du tableau de caractères, vous pouvez le parcourir avec une boucle pour la boucle.

for (int i = 0; i < myStringLen; i++)
{
     if (a[i] == someChar)
        //do something
}


12 commentaires

Il y a beaucoup de char * 's qui ne peut pas être utilisé comme chaîne de style C. Un 'Char *' pourrait être dirigé vers un seul caractère, ou un bloc de données, ou quoi que ce soit, vraiment.


Cela ne vous empêche toujours pas de l'indexer.


Cela fait, si cela ne pointe que d'un seul caractère. Dans ce contexte, il pourrait être absurde d'en parler en termes d'indexation "d'indexation".


Eh bien, nous ne parlons pas de ce contexte, maintenant sommes-nous? La question initiale a spécifiquement interrogé sur une chaîne.


Mais vous êtes quand vous dites: "N'oubliez pas que un char * peut être utilisé comme chaîne de style C".


@Arafangion En outre, pour l'enregistrement, je viens de le tester avec un seul char et que vous pouvez toujours l'indexer. VC ++ 2010. Je peux vous envoyer le code si vous le souhaitez.


Oui. Qu'en est-il de ce code? pour (int i = 0; i [a]; ++ i) {if (i [a] == somechar) {...}}. Et non, ce n'est pas une erreur. Est-ce que cela "prouve" que je peux indexer i avec un? Dans cette situation, tout ce que vous dites, c'est que vous pouvez faire du pointeur arithmétique avec un «char *», ce qui est un pointeur, il n'ya donc aucune surprise là-bas.


int main () {char * myTest = nouveau caractère; mytest [0] = 's'; STD :: COUT << "valeur de mon test à 0:" << myTest [0] << "\ n"; système ("pause"); Supprimer MyTest; retour 0; } (Désolé pour le formatage, je ne sais vraiment pas comment le formater dans des commentaires).) Vous avez expressément dit qu'il ne pouvait pas être indexé. Je l'ai donc indexé avec 0. Vous n'avez jamais spécifié avec quoi. Indexation Char * I avec INT A peut échouer dans une situation quelconque, qu'il s'agisse ou non d'une chaîne de style C.


Je voudrais aussi ajouter que oui, je reçois au pointeur arithmétique. Pourquoi je ne serais-je pas? Il est synonyme d'indexation, le compilateur sortira la même chose pour les deux. En disant que je peux faire du pointeur arithmétique à ce sujet, vous avez assez d'accord avec moi.


Sauf que ce n'est pas exactement la même chose, et cela est confus aux débutants qu'ils sont différents. Il est préférable de leur montrer des tableaux et de leur montrer des pointeurs, puis de déterminer comment les tableaux sont généralement mis en œuvre. Considérez que la taille de l'opérateur diffère des tableaux VS VS.


Sauf qu'ils sont les mêmes que le compilateur est concerné. publications.gbdirect.co.uk/c_book/chapter5/pointsers.htmlLle_ > Voir la section 5.3.2, Exemple 5.3 (Lisez le paragraphe ci-dessus). En outre, j'ai montré des tableaux n'est-ce pas? Je n'ai même pas mentionné le pointeur arithmétique avant de l'avoir apporté.


C'est un bon lien, mettez cela dans la réponse et je vais vous uppoter. :)



22
votes

Autre moyen:

char * i;

for (i=a; *i; i++) {
   // i points successively to a[0], a[1], ... until a '\0' is observed.
}


11 commentaires

En effet, mais vous devez alors explicitement déréférence i à l'intérieur de votre pour boucle que vous n'avez pas à faire avec a [foo] . Cela pourrait bouer la réponse pour un débutant.


Il peut être supérieur à d'autres manières car aucune addition supplémentaire ne se produit. Avec a [i] , il y a toujours l'addition A + i , où a est un pointeur et i i un nombre entier. Ceci est inférieur à juste i ++ i est un pointeur si a [i] resp. * i est utilisé plusieurs fois à l'intérieur de la boucle. Mais c'est une micro-optimisation.


A [FOO] est sténographique pour * (A + FOO). Dans l'apprentissage C, il est important qu'un étudiant reconnaisse que, à l'exception de la déclaration, l'utilisation des sous-domestiques et des arithmétiques du pointeur sont équivalentes. +1


Si vous êtes inquiet pour la micro-optimisation, je suggère d'utiliser ++ i préinCrètent non i ++ postincrement;)


Parfois ++, je serai moins efficace.


@Arafangion: Nonsense. Pourquoi sur Terre serait-il un agent de mise en œuvre sur leur chemin pour créer cette différence entre les deux?


@Arafangion n'est pas vrai dans le cas d'une boucle. Le compilateur est suffisamment intelligent pour faire des optimisations à ce sujet. ++ I est également l'une plus efficace dans la plupart des cas car elle ne crée pas une copie de i.


@MGZERO: "++ i est aussi le plus efficace" aussi non-sens. Ceci est C, pas C ++, et il n'y a absolument pas besoin d'un compilateur de faire une copie inutilisée de la valeur antérieure du i . ++ I ne pourrait être plus efficace que si "la plupart des cas" Si la plupart des codes sont optimisés très faibles, mais en considérant de près la performance du code non optimisé est assez futile. En C ++, il est vrai que pour des types définis par l'utilisateur, l'optimisation est un peu plus difficile en général et parfois impossible.


@Steve Jessop vous vous rendez compte que je suis d'accord avec vous, non? Deuxièmement, j'avais déjà noté que le compilateur effectue des optimisations dans les cas où la copie post-augmentation n'est pas nécessaire, comme dans le cas d'une boucle. Lire mon post maintenant, ça sonne comme je voulais dire autre chose ...


Pourquoi la boucle pour la boucle est-elle terminée lorsque * (i + 1) = '\ 0' ? Est-ce parce que '\ 0' provoque l'échec de la condition?


@Minhtran, il ne devrait pas le faire. Il ne faut que terminer uniquement si * i est \ 0 , pour des raisons évidentes ( \ 0 est l'octet null, qui est == 0 et évalue en faux contextes booléens).



3
votes

Comme ça.

char       a1[] = "STRING";
const char * a2 = "STRING";

char * c;     /* or "const char" for a2 */

for (c = aN; *c; ++c)
{
  /* *c is the character */
}


0 commentaires