• [^] # Re: strchr

    Posté par . En réponse au message sscanf et expressions régulières. Évalué à 1.

    Pour le dire d'une autre façon (un peu plus technique), mais tu sembles avoir tout compris :

    sp_fin = strchr(buffer, '\t');

    on récupère l'adresse de la prochaine tabulation (depuis 'buffer' qui contient l'adresse du début de la chaîne de caractères) dans un pointeur

    if (sp_fin == NULL) {
    continue;
    }

    si le pointeur est NULL, pas de tabulation trouvée, on saute (= on prend la prochaine ligne avec le 'fgets')

    *sp_fin = '0円';

    ça veut dire exactement cela : on met le caractère '0円' à l'adresse pointée par 'sp_fin' (qui doit pointer vers un '\t')

    strcpy(champ1, buffer);

    la fonction 'strcpy' s'arrête au caractère de fin de chaîne de caractère '0円' que nous avons introduit artificiellement en prenant soin de conserver son adresse pour pouvoir revenir en arrière et remettre le '\t' au bon endroit par la suite

    sp_debut = sp_fin + 1;

    on avance d'une 'case' dans la chaîne de caractère (d'où l'intérêt d'utiliser des pointeurs typés et non pas des 'void *' sinon la machine saurait pas la taille de '+ 1' qui n'est pas la même pour tous les types)

    pour conclure, je dirais que ce n'est pas "accrobatique" mais juste qu'il n'y a pas de fonction toute faite pour cela et qu'il faut décrire vraiment ce que l'on fait, c'est ça le C :o)

    si tu veux que ton travail soit réutilisable, fais toi une fonction qui copie le champ suivant à partir d'une adresse et d'un délimiteur, par exemple :

    char *cpy_next_field(char *field_buffer, char *string, char delim)
    {
    char *sp;

    if ((sp = strchr(string, delim)) == NULL) {
    return NULL;
    }
    *sp = '0円';
    strcpy(field_buffer, string);
    *sp = delim;
    return sp + 1;
    }

    et tu testes la valeur de retour qui est soit NULL si rien n'est trouvé, soit l'adresse du début du champ suivant

    on peut donc maintenant écrire ton programme comme cela :

    while (fgets(buffer, MAX_CHAR_BY_LINE, fp_XF86Config) != NULL) {
    sp = cpy_next_field(champ1, buffer, '\t');
    if (sp == NULL) {
    continue;
    }
    sp = cpy_next_field(champ2, sp, '\t');
    if (sp == NULL) {
    continue;
    }
    sp = cpy_next_field(champ3, sp, '\n');
    if (sp == NULL) {
    continue;
    }
    printf("c1 [%s] c2 [%s] c3 [%s]\n", champ1, champ2, champ3);
    }

    ce qui est quand même plus clair... et si demain tu veux utiliser un autre délimiteur, pas de problème :o)
    (la petite subtilité que tu as dû voir est que le dernier champ est délimité par un retour à la ligne '\n')