IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

(Exercice) Vérification d'une chaine de caractères - Besoin d'aide :)


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2022
    Messages : 2
    Points : 1
    Points
    1
    Par défaut (Exercice) Vérification d'une chaine de caractères - Besoin d'aide :)
    Bonjour à tous,

    Dans le cadre de nos études nous avons un exercice sur les chaines de caractères que nous n'arrivons pas a terminer (nous bloquons dessus depuis 4-5 jours).

    L'énoncé est le suivant :
    Ecrire un programme qui effectue des saisies de chaînes de caractères répondant à certains
    formats. Le programme doit définir et appeler une série de fonctions « lire... » qui permettront de
    récupérer, via getchar() (uniquement !), par paramètre, des chaînes formatées et de les afficher
    toutes, en fin de programme. Les fonctions attendues doivent permettre de saisir (et vérifier) :
    - un "réel positif ou nul" composé de maximum n (paramètre) chiffres avant la virgule et de maximum
    m (paramètre) chiffres après la virgule. Le séparateur partie entière/décimale est un caractère
    passé en paramètre. Un code d'erreur est retourné si la chaîne saisie ne correspond pas à ces
    critères.

    Après avoir posé des questions j'ai obtenu les informations suivantes en plus de l'énoncé :
    -Les étapes ) suivre sont les suivantes :
    1. Remplir la chaine
    2. Vérifier la 1ere partie (entière)
    3. Vérifier le séparateur (reçu dans la fonction par paramettre)
    4. Vérifier la dernière partie (décimale)

    Voici le code que nous avons fait mais il ne vérifie pas ...
    Toute aide serait la bienvenue.
    Merci d'avance à tous,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int flottant(int, int, char*, char*);
     
    int main()
    {
     
        char chaine[50];
        int n = 4;
        int m = 4;
        char v[2] = {',', '\0'};
     
        int k;
     
        printf("\nEntrez le nombre : ");
     
        k = flottant(n, m, &v, &chaine);
     
        printf("\nVoici la chaine : %s- FIN", chaine);
        printf("\nVoici le resultat (0 pour ok, >0 pour pas ok : %d", k);
     
     
        return 0;
    }
     
    int flottant(int n, int m, char *v, char *chaine)
    {
     
        char c;
     
     
        fflush(stdin);
        c = getchar();
        int i=0, k = 0;
        while ((i < 15) && (c != '\n'))
        {
            *chaine = c;
            chaine++;
            i++;
            c = getchar();
        }
        *chaine = '\0';
     
        i=0;
        printf ("Avant boucle i = %d, n = %d et m = %d\n", i, n, m);
        while ((i < n) || (*chaine != '\0'))        /*On va chercher la partie entière et le séparateur */
        {
            if (*chaine == '0'|| *chaine == '1' || *chaine == '2' || *chaine == '3' || *chaine == '4' || *chaine == '5' || *chaine == '6' || *chaine == '7' || *chaine == '8' || *chaine == '9'|| *chaine == '\0' || *chaine == '.')
            {
                printf ("Boucle 1 IF i = %d\n", i);
     
            }
            else
            {
                k++;
                i=n+m+1;
                printf ("Boucle 1 ELSE i = %d", i);
            }
            chaine++;
            i++;
        }
     
           while ((i < n + m + 1) || (*chaine != '\0'))
        {
            if (*chaine == '0'|| *chaine == '1' || *chaine == '2' || *chaine == '3' || *chaine == '4' || *chaine == '5' || *chaine == '6' || *chaine == '7' || *chaine == '8' || *chaine == '9'|| *chaine == '\0')
            {
                printf ("Boucle 2 IF i = %d\n", i);
     
            }
            else
            {
                k++;
                i=n+m+1;
                printf ("Boucle 2 ELSE i = %d", i);
            }
            chaine++;
            i++;
        }
     
    int z;
     
        /*for(i = 0; i < n || c != '\n'; i++, chaine++)
        {
            //c = getchar;
            if((c <= '0' || c >= '9') || (c != *v) || (c != '\o'))
                *chaine = c;
            else
                k++;
     
            c = getchar;
        }
     
        for(i; i < (n + m + 2) || c != '\n'; i++, chaine++)
        {
            //c = getchar();
            if((c < '0' || c > '9') || (c != *v))
                *chaine = c;
            else
                k++;
     
            c = getchar;
        }
            *(chaine-1) = '\0';*/
     
        return k;
    }

  2. #2
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    J'ai du mal avec le nom des variables: il faudrait des "noms parlants"...

    v <-> separateur, par exemple.

    Les commentaires dans le code ce serait pas mal pour décrypter... n, m, k, je vois pas à quoi ça sert, il faut deviner que ce sont des bornes, ou autre chose.
    Un code source ne doit pas forcément être compilé pour comprendre ce qu'il est censé faire... d'où les commentaires... quand on revient six mois après dans son code source même les instructions écrites par nous-mêmes sans commentaires ça devient pénible la (re) lecture du code source.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int flottant(int, int, char*, char*);
    ...deviendrait selon mon idéal de lecture de code source
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /* input:
    int: longueur partie entière
    int: longueur partie décimale
    char: séparateur
    char*: chaîne contenant un nombre en virgule flottante
     
    output:
    -1 signale une erreur
    */
     
    int flottant(int, int, char, char*);

    Pour le séparateur un char serait suffisant à mon humble avis...

    ...bon je vais compiler et voir ce que je peux faire...

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 631
    Points : 10 558
    Points
    10 558
    Par défaut
    En réalité tu ne testes rien
    Il faut avoir 1 variable booléen (en C c'est 1 entier, moi je préfère unsigned char). Et ce booléen doit arrêter ton algo "caractère par caractère" 1 fois qu'1 test ne passe pas.
    Pour les termes techniques , tu codes 1 machine à états ou 1 automate comme on dit en mathématiques.
    Et si tu te demandes , en C, l'encodage par défaut est l'ASCII. Et dans la table ASCII, les chiffres, les minuscules et les majuscules se suivent et sont dans l'ordre.

    Voici 1 exemple de code pour tester ton nombre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    #include <stdio.h>
    #include <stdlib.h>
     
     
    typedef enum e_error {
        ERROR_NONE = 0,
        ERROR_END,
        ERROR_EMPTY_PARAMETER,
        ERROR_FIRST_PART,
        ERROR_FIRST_PART_SIZE,
        ERROR_SEPARATOR,
        ERROR_SECOND_PART,
        ERROR_SECOND_PART_SIZE
    } t_error;
     
     
    char* get_error_str(t_error error) {
        switch (error) {
        case ERROR_NONE:             return "ERROR_NONE"; break;
        case ERROR_END:              return "ERROR_END"; break;
        case ERROR_EMPTY_PARAMETER:  return "ERROR_EMPTY_PARAMETER"; break;
        case ERROR_FIRST_PART:       return "ERROR_FIRST_PART"; break;
        case ERROR_FIRST_PART_SIZE:  return "ERROR_FIRST_PART_SIZE"; break;
        case ERROR_SEPARATOR:        return "ERROR_SEPARATOR"; break;
        case ERROR_SECOND_PART:      return "ERROR_SECOND_PART"; break;
        case ERROR_SECOND_PART_SIZE: return "ERROR_SECOND_PART_SIZE"; break;
        }
     
        return "unknow error";
    }
     
     
    unsigned char test_number(char* str, size_t n, size_t m, char sep, t_error* error) {
        unsigned char ret;
     
        if (str != NULL) {
            char* tmp_str=str;
            size_t count;
            char c;
     
            ret   = 1;
            count = 0;
            c     = (*tmp_str);
     
            while (ret & (c != '\0') && (count < n)) {
                if ((c >= '0') && (c <= '9')) {
    //              printf("%c -  ok [first part]\n", c);
     
                    ++tmp_str;
                    ++count;
                    c = (*tmp_str);
                } else {
                    ret = 0;
                    if (error != NULL) { (*error) = ERROR_FIRST_PART; }
     
    //              printf("%c - nok [first part]\n", c);
                }
            }
     
            if (ret) {
                c = (*tmp_str);
     
                if (c == sep) {
                    ++tmp_str;
                } else if (c != '\0') {
                    ret = 0;
                    if (error != NULL) { (*error) = (((c >= '0') && (c <= '9'))? ERROR_FIRST_PART_SIZE: ERROR_SEPARATOR); }
     
    //              printf("%c - nok [seperator]\n", c);
                }
            }
     
            count = 0;
            c     = (*tmp_str);
     
            while (ret & (c != '\0') && (count < m)) {
                if ((c >= '0') && (c <= '9')) {
    //              printf("%c -  ok [second part]\n", c);
     
                    ++tmp_str;
                    ++count;
                    c = (*tmp_str);
                } else {
                    ret = 0;
                    if (error != NULL) { (*error) = ERROR_SECOND_PART; }
     
    //              printf("%c - nok [second part]\n", c);
                }
            }
     
            if (ret) {
                if (c == '\0') {
                    if (error != NULL) { (*error) = ERROR_NONE; }
                } else {
                    ret = 0;
                    if (error != NULL) { (*error) = (((c >= '0') && (c <= '9'))? ERROR_SECOND_PART_SIZE: ERROR_END); }
                }
            }
        } else {
            ret = 0;
            if (error != NULL) { (*error) = ERROR_EMPTY_PARAMETER; }
        }
     
        return ret;
    }
     
     
    #define TEST_OK(STR, N, M, SEP, TEXT_STR) \
        if ( test_number(STR, N, M, SEP, &error) ) { \
            printf("%s  ok\n", TEXT_STR); \
        } else { \
            printf("%s nok - %s\n", TEXT_STR, get_error_str(error)); \
        }
     
     
    #define TEST_NOK(STR, N, M, SEP, TEXT_STR, ERR0R) \
        if ((!test_number(STR, N, M, SEP, &error)) && (error == ERR0R))  { \
            printf("%s  ok\n", TEXT_STR); \
        } else { \
            printf("%s nok - %s\n", TEXT_STR, get_error_str(error)); \
        }
     
     
    int main()
    {
        t_error error;
     
        TEST_OK("125",        3, 4, '.', "test first part                ");
        TEST_OK("125.",       3, 4, '.', "test first part + sep          ");
        TEST_OK("125.44",     3, 4, '.', "test full                      ");
        TEST_NOK("12a.44",    3, 4, '.', "test error first part          ", ERROR_FIRST_PART);
        TEST_NOK("125a44",    3, 4, '.', "test error sep                 ", ERROR_SEPARATOR);
        TEST_NOK("125.4a",    3, 4, '.', "test error second part         ", ERROR_SECOND_PART);
        TEST_NOK("1258.459",  3, 4, '.', "test error first part too long ", ERROR_FIRST_PART_SIZE);
        TEST_NOK("125.45974", 3, 4, '.', "test error second part too long", ERROR_SECOND_PART_SIZE);
     
    //  Others tests
     
        return EXIT_SUCCESS;
    }
    Édit : TEST_NOK doit tester l'erreur

  4. #4
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    houlà foetus t'as été bien plus vite que moi lol ^^

  5. #5
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    Y a rien à faire je HAIS le getchar() standard...

    Ca vaut ce que ça vaut...

    [EDIT]
    Dans le code source dans les commentaires le copié/collé a foiré...
    Concernant la fonction getchar() si on ne la modifie pas à ma manière nous ne sommes pas en mesure de valider le caractère entré à chaque frappe au clavier,
    il faut attendre qu'on appuye sur "return" pour valider les entrées... j'ai basé mon approche sur getch() qui utilise un getchar() modifié...

    La fonction getch() saisi un caractère puis retourne à la fonction appelante, elle ne fait pas l'écho du caractère saisi (il faut le faire soi-même)
    Fichiers attachés Fichiers attachés

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2022
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonjour à tous,

    Merci beaucoup pour vos éclaircissements.
    Permettez moi également de vous présenter toutes mes excuses pour les commentaires manquants.
    Je comprends une bonne partie de votre aide, mais nous sommes en 1ère année, n'avons pas été si en c et n'avons pas (encore) vu les fonctions que vous utilisez (nous n'avons eu cours que 3 mois à hauteur de 5 h / semaine labos inclus).
    A cela s'ajoute le fait de reprendre les études (à distance) à 36 et 26 ans, tout en travaillant (dans la compta) à 2000 km de l'école et n'y retourner qu'une semaine avant les examens. Cela nous demande un effort supplémentaire pour être à jour par tout. Mais bon nous avons la chance d'avoir des profs (généralement) compréhensifs et qui sont assez disponibles pour nous aider, cela nous a permis de réussir l'ensemble des examens de janvier sans repêches.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Sebarby Voir le message
    Voici le code que nous avons fait mais il ne vérifie pas ...
    J'ai pas tou lu le code d'origine (effectivement des variables comme "m", "n", "k" c'est pas super parlant) mais il y a un truc qui m'a choqué: ce while ((i < n + m + 1) || (*chaine != '\0')). Tu as bien conscience que la boucle se fera si l'une des deux conditions seulement est vraie, autrement dit simplement si tu n'es pas sur le '\0' de la chaine et la première évaluation ne sert à rien.
    Peut-être n'as-tu pas bien saisi que si une proposition est faite avec "or", alors sa négation est faite via "and". Je veux continuer si j'ai X ou Y implique que je veux m'arrêter si je n'ai pas X et pas Y.
    Ces règles ont été formalisées par De Morgan au XIX° siècle
    • non (A et B) = non(A) ou non(B)
    • non (A ou B) = non(A) et non(B)


    Accessoirement tu peux remplacer char v[2] = {',', '\0'} par char v[]="," (le compilateur remplace la string par un tableau de char terminé par '\0' et s'occupe de compter quelle taille doit avoir le tableau) et comme hurukan l'a dit, une chaine ne contenant qu'un caractère peut alors être remplacée par un simple char (sauf si ton "v" doit être ensuite utilisé dans des fonctions comme strstr() ou autres fonctions de recherche de chaine).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. [WD14] Vérification d'une chaine de caractère
    Par pixel016 dans le forum WinDev
    Réponses: 4
    Dernier message: 25/02/2011, 09h50
  2. vérification de la longueur d'une chaine de caractère
    Par midodido123 dans le forum Développement de jobs
    Réponses: 3
    Dernier message: 04/08/2009, 10h24
  3. Vérification d'une chaine de caractères
    Par sandrine49 dans le forum PL/SQL
    Réponses: 3
    Dernier message: 23/06/2009, 21h05
  4. vérification de la longeur d'une chaine de caractère
    Par youcef_b_dz dans le forum Delphi
    Réponses: 5
    Dernier message: 23/08/2006, 15h51
  5. Réponses: 2
    Dernier message: 06/12/2002, 07h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo