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 :

Sécurité des saisies


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Haïti

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 29
    Points : 38
    Points
    38
    Par défaut Sécurité des saisies


    Salut à tous!!!!

    Je veux entrer une fonctionnalité dans un programme qui concerne la saisie.
    En programmant, si la saisie n'est pas sécurisée on risque d'obtenir de nombreux bugs ou de résultats vraiment obsolètes.

    Mon problème c'est comment s'assurer que l'utilisateur entrera un chiffre quand on demande un chiffre ou un caractère quand on demande un caractère.
    Si il entre un caractère en lieu et place d'un chiffre cela ne causera pas de problème vu que ce caractère sera converti en un nombre quelconque dépendemment de l'ordinateur.

    Donc ma question, comment s'assurer que même quand il saisie une lettre le programme redemendera d'entrer le bon éléments.
    On ne va quand même pas lister tous les lettres de l'alphabets (majuscules et minuscules ) dans une boucle do{}while(); pour empecher cela.
    C'est beaucoup!!!!!!!

    Je suis sure qu'il y a une facon plus simple de faire

    Ainsi, a-t-il été exposé mon problème.

    Merci déjà de me preter main forte dans ma recherche

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Bonjour,

    Soit tu utilises des bibliothèques spécialisées dans les masques de saisie, soit tu t'arranges au préalable pour recevoir directement les caractères saisis par l'utilisateur (les terminaux UNIX les bufferisent par défaut et les envoient sur un retour à la ligne) et tu contrôles la validité du caractère.

    Pour faire cette validation, tu n'es pas forcément obligé de tester une à une les valeurs légitimes. Les codes des caractères ASCII sont faits pour être consécutifs pour la plupart. Par exemple, si tu veux vérifier que le caractère contenu dans « c » est un chiffre entre 0 et 9, tu peux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if (c>='0' && c<='9')
        {}

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Il existe aussi des fonctions standard de classification des caractères : isdigit(), isalpha(),... (cf <ctype.h>)
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  4. #4
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Il faut faire attention aussi au fait qu'une entrée numérique valide peut comporter d'autres caractères que des chiffres : moins, plus, virgule et/ou point, éventuellement espaces, e ou E pour un flottant...

    Inversement, une entrée qui ne comporte que des chiffres ne forme pas forcément un entier valide pour ton programme puisque tu peux avoir un débordement.

    En pratique plutôt que de valider chaque caractère indépendamment des autres, il est souvent plus simple et plus sûr de valider l'entrée complète. Par exemple si tu attends un entier, tu vas probablement utiliser strtol() pour faire la conversion, et si elle est utilisée correctement cette fonction donnera une erreur si l'entrée ne représente pas un entier.

    Attention d'ailleurs, certaines fonctions de comparaison (atoi() par exemple) ne permettent pas toujours de gérer les erreurs de façon satisfaisante (atoi() par exemple revoie 0 en cas d'erreur, mais aussi si l'entrée représente le nombre 0).

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Haïti

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 29
    Points : 38
    Points
    38
    Par défaut Renseignement
    Citation Envoyé par matafan Voir le message
    Il faut faire attention aussi au fait qu'une entrée numérique valide peut comporter d'autres caractères que des chiffres : moins, plus, virgule et/ou point, éventuellement espaces, e ou E pour un flottant...

    Inversement, une entrée qui ne comporte que des chiffres ne forme pas forcément un entier valide pour ton programme puisque tu peux avoir un débordement.

    En pratique plutôt que de valider chaque caractère indépendamment des autres, il est souvent plus simple et plus sûr de valider l'entrée complète. Par exemple si tu attends un entier, tu vas probablement utiliser strtol() pour faire la conversion, et si elle est utilisée correctement cette fonction donnera une erreur si l'entrée ne représente pas un entier.

    Attention d'ailleurs, certaines fonctions de comparaison (atoi() par exemple) ne permettent pas toujours de gérer les erreurs de façon satisfaisante (atoi() par exemple revoie 0 en cas d'erreur, mais aussi si l'entrée représente le nombre 0).
    Matafan, je te remercie deja pour ton poste:
    La je besoin que tu me parles un peu plus sur les fonctions tel atoi(),atof(),atol()
    Mon probleme avec c'est que je ne sais pas exactement dans quell bibliotheque elles se trouvent

  6. #6
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2007
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 178
    Points : 451
    Points
    451
    Par défaut
    Citation Envoyé par alexisleprogrammeur Voir le message
    La je besoin que tu me parles un peu plus sur les fonctions tel atoi(),atof(),atol()
    Mon probleme avec c'est que je ne sais pas exactement dans quell bibliotheque elles se trouvent
    C'est dans stdlib :
    http://man.developpez.com/man3/atoi.3.php

    Encore une fois "strtol" est plus sûr...

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Si on parle de sécurité des saisies, il est évident qu'on banni les fonctions de la famille d'atoi() ! +1 pour pythéas !

    Je redonne aussi un lien qu'on donne tout le temps ici : http://emmanuel-delahaye.developpez....ees-solides-c/

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Haïti

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 29
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par pythéas Voir le message
    C'est dans stdlib :
    http://man.developpez.com/man3/atoi.3.php

    Encore une fois "strtol" est plus sûr...

    Pytheas Merci piur tes conseils
    Je voudrais juste que tu me donnes le prototype de la fonction strtol()
    Car en compilant on me doit qu'il me manque un argument...

  9. #9
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2007
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 178
    Points : 451
    Points
    451
    Par défaut
    http://www.cplusplus.com/reference/cstdlib/strtol/

    Bon c'est un site c++ mais ça change pas grand chose.

    Sinon c'est vraiment pas une info difficile à trouver

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par pythéas Voir le message
    Bon c'est un site c++ mais ça change pas grand chose.

    Sinon c'est vraiment pas une info difficile à trouver
    Sinon, il y a les man pages :
    http://man.developpez.com/man3/strtol.3.php

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    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 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Un peu de retard mais j'étais absent. +1 pour l'intervention de bktero.

    Moi, si je veux faire une saisie vérifiée, j'utilise fgets() pour que le buffer clavier soit bien entièrement récupéré puis ensuite sscanf() pour extraire de la chaine saisie l'élément qui m'intéresse. Et chose avantageuse, sscanf() renvoie le nb d'éléments correctement extraits...

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    char saisie[255];
    int nb;
     
    while (1)
    {
        printf("Saisissez un nombre: "); fflush(stdout);
        fgets(saisie, 255, stdin);
        if (sscanf(saisie, "%d", &nb) == 1) break;
        printf("Erreur - [%s] n'est pas un nombre - Recommencez\n", saisie);
    }
    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]

  12. #12
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Salut,

    Voici une fonction de saisie "sécurisée".

    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
     
    int read_stdin( char *buffer, unsigned int *length )
    {
        if ( buffer )
        {
            if ( fgets( buffer, *length, stdin ) )
            {
                *length=0;
                while ( *buffer != '\0' )
                {
                    if ( *buffer == '\n' )
                        *buffer = '\0';
     
                    buffer++; (*length)++;
                }
                       fflush(stdin);
                       return 1;
            }
            else return 0;
        }
       else return -1;
    }
    A la fin de la saisie, tu peux faire un contrôle sur ce que l'utilisateur a entré et faire un appel récursif de cette fonction si le résultat ne te convient pas.

    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
     
    //Fonction qui compte le nombre d'occurrence d'un caractère dans une chaine
    unsigned long long int str_count_occurrence(char *s, char c)
    {
        unsigned  int o = 0;
        while( *s != '\0')
        {
            if ( *s == c )
                o++;
     
            s++;
        }
        return o;
    }
     
    //Fonction qui vérifie si le caractère c est contenu dans la list c_list
    unsigned int is_in_list(char c, char *c_list)
    {
        unsigned int i;
        for (i=0 ; i<str_length(c_list) ; i++ )
            if ( c == c_list[i] )
                return TRUE;
     
        return FALSE;
    }
     
    //Fonction qui vérifie si le caractère c est une lettre minuscule ou majuscule
    unsigned long long int is_alpha( char c )
    {
        if ( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
            return TRUE;
     
        else return FALSE;
    }
     
    //Fonction qui vérifie si le caractère C est un chiffre
    unsigned int is_numeric( char c )
    {
        if ( '0' <= c && c <= '9')
            return TRUE;
     
        else return FALSE;
    }
     
    //Fonction qui compte le nombre de caractères alphabétique contenu dans la chaine s
    unsigned int str_count_alpha( char *s )
    {
        unsigned long long int counter=0;
        while ( *s != '\0' )
        {
            if ( is_alpha(*s) == TRUE )
                counter++;
     
            s++;
        }
        return counter;
    }
     
    //Fonction qui compte le nombre de caractères numériques contenu dans la chaine s
    unsigned int str_count_numeric( char *s )
    {
        unsigned long long int counter=0;
        while ( *s != '\0' )
        {
            if ( is_numeric(*s) )
                counter++;
     
            s++;
        }
        return counter;
    }
     
    //Fonction qui vérifie si la chaine de caractères s est purement alphabétique
    unsigned int str_is_alpha(char *s)
    {
        while (*s != '\0')
        {
            if ( is_alpha(*s) == FALSE )
                return FALSE;
     
            s++;
        }
        return TRUE;
    }
     
    //Fonction qui vérifie si la chaine de caractères s est purement numérique
    unsigned int str_is_numeric(char *s)
    {
        while (*s != '\0')
        {
            if ( is_numeric(*s) == FALSE )
                return FALSE;
     
            s++;
        }
        return TRUE;
    }
    Cordialement.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Haïti

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 29
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par darkwall_37 Voir le message
    Salut,

    Voici une fonction de saisie "sécurisée".

    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
     
    int read_stdin( char *buffer, unsigned int *length )
    {
        if ( buffer )
        {
            if ( fgets( buffer, *length, stdin ) )
            {
                *length=0;
                while ( *buffer != '\0' )
                {
                    if ( *buffer == '\n' )
                        *buffer = '\0';
     
                    buffer++; (*length)++;
                }
                       fflush(stdin);
                       return 1;
            }
            else return 0;
        }
       else return -1;
    }
    A la fin de la saisie, tu peux faire un contrôle sur ce que l'utilisateur a entré et faire un appel récursif de cette fonction si le résultat ne te convient pas.

    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
     
    //Fonction qui compte le nombre d'occurrence d'un caractère dans une chaine
    unsigned long long int str_count_occurrence(char *s, char c)
    {
        unsigned  int o = 0;
        while( *s != '\0')
        {
            if ( *s == c )
                o++;
     
            s++;
        }
        return o;
    }
     
    //Fonction qui vérifie si le caractère c est contenu dans la list c_list
    unsigned int is_in_list(char c, char *c_list)
    {
        unsigned int i;
        for (i=0 ; i<str_length(c_list) ; i++ )
            if ( c == c_list[i] )
                return TRUE;
     
        return FALSE;
    }
     
    //Fonction qui vérifie si le caractère c est une lettre minuscule ou majuscule
    unsigned long long int is_alpha( char c )
    {
        if ( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
            return TRUE;
     
        else return FALSE;
    }
     
    //Fonction qui vérifie si le caractère C est un chiffre
    unsigned int is_numeric( char c )
    {
        if ( '0' <= c && c <= '9')
            return TRUE;
     
        else return FALSE;
    }
     
    //Fonction qui compte le nombre de caractères alphabétique contenu dans la chaine s
    unsigned int str_count_alpha( char *s )
    {
        unsigned long long int counter=0;
        while ( *s != '\0' )
        {
            if ( is_alpha(*s) == TRUE )
                counter++;
     
            s++;
        }
        return counter;
    }
     
    //Fonction qui compte le nombre de caractères numériques contenu dans la chaine s
    unsigned int str_count_numeric( char *s )
    {
        unsigned long long int counter=0;
        while ( *s != '\0' )
        {
            if ( is_numeric(*s) )
                counter++;
     
            s++;
        }
        return counter;
    }
     
    //Fonction qui vérifie si la chaine de caractères s est purement alphabétique
    unsigned int str_is_alpha(char *s)
    {
        while (*s != '\0')
        {
            if ( is_alpha(*s) == FALSE )
                return FALSE;
     
            s++;
        }
        return TRUE;
    }
     
    //Fonction qui vérifie si la chaine de caractères s est purement numérique
    unsigned int str_is_numeric(char *s)
    {
        while (*s != '\0')
        {
            if ( is_numeric(*s) == FALSE )
                return FALSE;
     
            s++;
        }
        return TRUE;
    }
    Cordialement.
    Enfin je demande de l'aide...
    Suite au commentaire de blackwall_37 j'ai cherché à mieux comprendre l'utilisation du pointeur dans bon nombre des fonction. Ces pointeurs sont de types CHAR.
    ils sont la pour accéder à des adresses. Leurs arguments effectifs n'auront pas le charactère & puisque un tableau de charactère est un pointeur.


    Il me semble que j'ai un peu de lacune en ce qui concerne les pointeurs.
    Je n'arrive pas à bien saisir le syntaxe et aussi la théorie qui se cache derrière.

    Jusque là mon problème n'a pas été présenté parfaitement mais je pense que vous pourrez me donner un brin d'explication et aussi des références pour que je puisse me tirer de cette mauvaise passe...

  14. #14
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Bonjour!

    Pour faire simple avec les pointeurs, il faut partir de la notion de mémoire.

    à la base, un ordinateur, c'est des atomes mémoires (les bits), et des transistors pour les modifier.

    Une variable est deux choses:
    • une valeur binaire (00101010), liée, par son utilisation, à un type et donc une valeur (int => 42)
    • une adresse dans la mémoire, pour pouvoir la retrouver.


    Cette adresse est simplement le numéro de la case mémoire, en commencant gentillement par 0, et allant jusqu'à … ca dépend de la taille des adresses (32 bits ou 64 bits).

    Chaque programme reçoit une simulation de l'ensemble de la RAM, c'est à dire que, chaque programme peut utiliser chaque adresse de 0 à ADRESSE_MAX.

    Si tu écris int entier = 32;, le compilateur génère en théorie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //chercher une case libre de bonne taille pour entier
    position<"entier"> = prochaine_position_libre;
    prochaine_position_libre += sizeof(int);
    //donner à entier sa valeur
    valeur<position<"entier">> = 32;
    En pratique, c'est une autre histoire, parce qu'il existe des registres, que des centaines d'optimisations ont leur mot à dire…

    Un int fait plusieurs bytes, donc occupe plusieurs cases successives, mais je laisse ce détail pour l'instant.

    Un pointeur, c'est juste une variable normale, dont le type est "adresse mémoire, d'un type donné".

    Le code int *pointeur; définit une variable, nommée pointeur, et dont le type est pointeur d'entier.
    Elle peut donc recevoir l'adresse d'une variable de type int.

    Personnellement, j'aime dire que int *pointeur; déclare "ce que pointerait la variable pointeur est un entier".
    Pourquoi? parce que de même que int a, b; définit deux "int" (a et b), int * pointeur, alpha; définit "ce que pointerait pointeur" et alpha comme deux int.

    Une question doit te venir en tête: comment donner une valeur à un pointeur?
    C'est le rôle de l'opérateur d'adressage, & (l'opérateur unaire…)
    Si alpha est une variable, alors &alpha est son adresse.
    Tu peux donc écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int entier = 42;
    int *pointeur = &entier;
    L'opération inverse est l'opérateur de déréferencement: *
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int entier = 42;
    int *pointeur = &entier;
    *pointeur = 27;
    //entier contient maintenant 27
    Les deux intérêts du pointeurs sont: le passage de paramètres et l'arithmétiques de pointeurs (et la "confusion tableau-pointeur")

    Pour le passage de paramètres d'une fonction, les valeurs de paramètres sont copiés.
    Par exemple, ce programme affichera "7 2":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdio.h>
    void fonction(int entier, int *pointeur) {
        entier=2;
        *pointeur=2;
    }
    int main(){
        int alpha =7, beta =7;
        fonction(alpha, &beta);
        printf("%d %d", alpha, beta);
        return 0;
    }
    Que fait ce programme?
    • création des deux entiers alpha et beta, chacun recevant la valeur 7;
    • création de deux temporaires, entier et pointeur.
    • copie de la valeur de alpha dans entier.
    • copie de la valeur de &beta dans pointeur.
    • fonction modifie s'effectue: entier vaut 2, et "ce qui est pointé par" pointeur vaut 2 aussi. C'est à dire la valeur à l'emplacement dont l'adresse est celle contenue dans pointeur, qui est la copie de l'adresse de beta, c'est à dire, beta.
    • oubli des temporaires entier et pointeur
    • affichage de alpha et beta.
    • fin du programme avec retour de la valeur 0 (succès, donc)


    Pour les tableaux, c'est autre façon de voire la chose. Supposons int tableau[3] = {1, 2, 3};.
    Alors tableau est un bloc mémoire contigu, dont la taille est 3*sizeof (int).
    Le C permet d'utiliser tableau comme un pointeur vers le premier élément de ce tableau.
    Ceci à deux effets: *tableau et tableau[0] sont la même variable, le premier int du bloc désigné par tableau.

    plus fort, il est possible d'ajouter un décallage (entier) à un pointeur.
    (pointeur+2) est une expression dont la valeur est l'adresse situé 2 <type pointé par pointeur> plus loin que celle contenu dans pointeur. C'est une adresse du même type que celle contenu dans pointeur, et utilisable de la même manière: *(pointeur+2) = 2;Attention, énorme soucis: pour avoir le droit de déréférencer cette adresse, il faut qu'elle appartienne au programme (sous peine de "segmentation fault"). C'est vrai pour tout pointeur, mais l'arithmétique de pointeur est l'art de se tromper facilement…

    Le point commun dans cette histoire?
    *(tableau+1), *(1+tableau), tableau[1], 1[tableau] sont quatre noms de la même variables, de même que *(&(tableau[2]) -1)

    L'autre lien, c'est la notion de distance mémoire: [codeinline]ptrdiff_t distance = &(tableau[2]) - &(tableau);(codeinline] déclare une variable dont la valeur est la différence entre les deux adresses, exprimée comme multiple de sizeof(int).
    La différence de deux pointeurs (de même type), est la taille du tableau allant de l'un à l'autre.

    J'espère t'avoir apporté quelques éclaircissement. Pour plus d'informations, lit donc la faq.

    Bonne journée, et félicitation d'avoir lu jusque ici!
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  15. #15
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    Bonjour,

    Citation Envoyé par darkwall_37 Voir le message
    Salut,

    Voici une fonction de saisie "sécurisée".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /* ... */
                       fflush(stdin);
    /* ... */
    « sécurisée » ne s'oppose pourtant pas à standard, il me semble.

    Bonne journée !
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  16. #16
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par Kirilenko Voir le message
    Bonjour,



    « sécurisée » ne s'oppose pourtant pas à standard, il me semble.

    Bonne journée !
    ? "sécurisée"
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  17. #17
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    Citation Envoyé par darkwall_37 Voir le message
    ? "sécurisée"
    Puisque tu sembles considérer mon précédent message comme étant faux (vote contre implique), comment justifies-tu l'utilisation de ce comportement indéterminé ?

    fflush (stdin) n'est pas dangereux en soi ; il s'agit simplement d'une habitude erronée. Aussi dénonçais-je pas tant l'emploi de « "sécurisée" », que l'incohérence de ton code source.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  18. #18
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par Kirilenko Voir le message
    fflush (stdin) n'est pas dangereux en soit ; il s'agit simplement d'une habitude erronée. Aussi dénonçais-je pas tant l'emploi de « "sécurisée" », que l'incohérence de ton code source.
    Tu peux même ajouter : « il y a de fortes chances que ça ne marche pas ».

  19. #19
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par Kirilenko Voir le message
    Puisque tu sembles considérer mon précédent message comme étant faux (vote contre implique), comment justifies-tu l'utilisation de ce comportement indéterminé ?

    fflush (stdin) n'est pas dangereux en soit ; il s'agit simplement d'une habitude erronée. Aussi dénonçais-je pas tant l'emploi de « "sécurisée" », que l'incohérence de ton code source.
    C'est ce que je dis, d'où le rappel de l'utilisation des guillemets (en rouge) lorsque j'utilise le terme sécurisée.
    Je ne dis pas que ce que vous dites est faux. Surtout moi, je ne me permettrais pas.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  20. #20
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Ce que veulent dire Kirilenko et Obsidian, c'est que tu ne peux pas faire un code sécurisé (par nature fiable) avec des opérations au comportement indéterminé (qui sont pas nature non fiables), tel que fflush(stdin).

Discussions similaires

  1. Sécurité des sites internet
    Par aloha dans le forum Dépannage et Assistance
    Réponses: 3
    Dernier message: 13/02/2006, 21h18
  2. [Sécurité] onglet Sécurité des options du dossier
    Par zsoh dans le forum Sécurité
    Réponses: 12
    Dernier message: 11/01/2006, 23h12
  3. [Sécurité] Sécurité des sessions
    Par nerik38 dans le forum Langage
    Réponses: 2
    Dernier message: 01/12/2005, 14h41
  4. [ACCESS97] Sécurité des applications
    Par mpascolo dans le forum Sécurité
    Réponses: 5
    Dernier message: 26/10/2005, 15h02

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