web-dev-qa-db-fra.com

Comment itérer sur une chaîne en C?

En ce moment j'essaye ceci:

#include <stdio.h>

int main(int argc, char *argv[]) {

    if (argc != 3) {

        printf("Usage: %s %s sourcecode input", argv[0], argv[1]);
    }
    else {
        char source[] = "This is an example.";
        int i;

        for (i = 0; i < sizeof(source); i++) {

            printf("%c", source[i]);
        }
    }

    getchar();

    return 0;
}

Cela ne fonctionne pas non plus:

char *source = "This is an example.";
int i;

for (i = 0; i < strlen(source); i++){

    printf("%c", source[i]);
}

Je reçois l'erreur

Exception non gérée à 0x5bf714cf (msvcr100d.dll) dans Test.exe: 0xC0000005: Violation d'accès lors de la lecture à la position 0x00000054.

(traduit librement de l'allemand)

Alors qu'est-ce qui ne va pas avec mon code?

48
Vincent

Tu veux:

for (i = 0; i < strlen(source); i++){

sizeof vous donne la taille du pointeur, pas la chaîne. Cependant, cela aurait fonctionné si vous aviez déclaré le pointeur comme un tableau:

char source[] = "This is an example.";

mais si vous passez le tableau à fonctionner, cela se décomposera également en un pointeur. Pour les chaînes, mieux vaut toujours utiliser strlen. Et notez ce que d’autres ont dit sur le changement de printf pour utiliser% c. De plus, en tenant compte des commentaires de mmyers sur l’efficacité, il serait préférable de sortir l’appel de strlen de la boucle:

int len = strlen( source );
for (i = 0; i < len; i++){

ou réécrire la boucle:

for (i = 0; source[i] != 0; i++){
55
anon

Un idiome commun est:

char* c = source;
while (*c) putchar(*c++);

Quelques notes:

  • En C, les chaînes sont terminaison par null . Vous parcourez alors que le caractère lu n'est pas le caractère nul.
  • *c++ Incrémente c et renvoie la valeur déréférencée old de c.
  • printf("%s") affiche une chaîne terminée par un caractère null, pas un caractère. Ceci est la cause de votre violation d'accès.
39
Alexandre C.

Plutôt que d'utiliser strlen comme suggéré ci-dessus, vous pouvez simplement rechercher le caractère NULL:

#include <stdio.h>

int main(int argc, char *argv[])
{
    const char *const pszSource = "This is an example.";
    const char *pszChar = pszSource;

    while (pszChar != NULL && *pszChar != '\0')
    {
        printf("%s", *pszChar);
        ++pszChar;
    }

    getchar();

    return 0;
}
3
Mark Ingram

sizeof(source) renvoie le nombre d'octets requis par le pointeur char*. Vous devriez le remplacer par strlen(source) qui sera la longueur de la chaîne que vous essayez d'afficher.

En outre, vous devriez probablement remplacer printf("%s",source[i]) par printf("%c",source[i]) puisque vous affichez un caractère.

2
Jacob

Cela devrait marcher

 #include <stdio.h>
 #include <string.h>

 int main(int argc, char *argv[]){

    char *source = "This is an example.";
    int length = (int)strlen(source); //sizeof(source)=sizeof(char *) = 4 on a 32 bit implementation
    for (int i = 0; i < length; i++) 
    {

       printf("%c", source[i]);

    }


 }
2
Prasoon Saurav
  1. sizeof () inclut le caractère nul final. Vous devez utiliser strlen () (mais mettre l'appel en dehors de la boucle et l'enregistrer dans une variable), mais ce n'est probablement pas ce qui cause l'exception.
  2. vous devez utiliser "% c" et non pas "% s" dans printf - vous imprimez un caractère, pas une chaîne.
2
KenE
  • sizeof(source) vous renvoie la taille d'un char*, pas la longueur de la chaîne. Vous devriez utiliser strlen(source) et le déplacer hors de la boucle, sinon vous recalculerez la taille de la chaîne à chaque boucle.
  • En imprimant avec le modificateur de format %s, printf recherche un char*, Mais vous passez en réalité un char. Vous devriez utiliser le modificateur %c.
1
JSBձոգչ

Il suffit de changer sizeof avec strlen.

Comme ça:

char *source = "This is an example.";
int i;

for (i = 0; i < strlen(source); i++){

    printf("%c", source[i]);

}
0
Pablo Santa Cruz

Remplacez sizeof par strlen et cela devrait fonctionner.

0
Keith Randall

Vous avez besoin d'un pointeur sur le premier caractère pour avoir une chaîne ANSI.

printf("%s", source + i);

va faire le travail

De plus, vous auriez naturellement dû parler de strlen(source) et non de sizeof(source).

0
ULysses

sizeof(source) retourne la taille d'un pointeur car la source est déclarée char *. La façon correcte de l'utiliser est strlen(source).

Prochain:

printf("%s",source[i]); 

attend de la ficelle. c.-à-d.% s attend une chaîne, mais vous effectuez une itération en boucle pour imprimer chaque caractère. Par conséquent, utilisez% c.

Cependant, votre manière d'accéder (à une itération) à une chaîne en utilisant l'index i est correcte et par conséquent, elle ne pose aucun autre problème.

0
Praveen S

Le dernier index d'une chaîne de caractères est toujours la valeur entière 0, d'où l'expression "chaîne terminée par un caractère nul". Comme l'entier 0 est identique à la valeur booléenne false en C, vous pouvez l'utiliser pour créer une clause while simple pour votre boucle for. Lorsqu'il atteint le dernier index, il trouve un zéro et le compare à false, terminant la boucle for.

for(int i = 0; string[i]; i++) { printf("Char at position %d is %c\n", i, string[i]); }
0
Edwin Jata