Précédent   Forum du club des développeurs et IT Pro > C et C++ > C > Débuter
Débuter Forum d'entraide pour débuter en langage C. Avant de poster -> FAQ C
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 20/02/2013, 04h37   #1
alexisleprogrammeur
Membre à l'essai
 
Homme Rulx Philome Alexis
Étudiant
Inscription : janvier 2013
Messages : 19
Détails du profil
Informations personnelles :
Nom : Homme Rulx Philome Alexis
Localisation : Haïti

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

Informations forums :
Inscription : janvier 2013
Messages : 19
Points : 23
Points : 23
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
alexisleprogrammeur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/02/2013, 06h06   #2
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 095
Points : 11 095
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 :
1
2
3
4
    if (c>='0' && c<='9')
    {}
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/02/2013, 10h11   #3
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 434
Détails du profil
Informations personnelles :
Nom : Homme Patrick Gonord
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Enseignement

Informations forums :
Inscription : juin 2005
Messages : 5 434
Points : 12 955
Points : 12 955
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 !
diogene est déconnecté   Envoyer un message privé Réponse avec citation 50
Vieux 20/02/2013, 14h06   #4
matafan
Membre Expert
 
Homme
Ingénieur développement logiciels
Inscription : octobre 2008
Messages : 1 482
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 34
Localisation : France

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

Informations forums :
Inscription : octobre 2008
Messages : 1 482
Points : 2 438
Points : 2 438
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 est déconnecté   Envoyer un message privé Réponse avec citation 30
Vieux 20/02/2013, 23h23   #5
alexisleprogrammeur
Membre à l'essai
 
Homme Rulx Philome Alexis
Étudiant
Inscription : janvier 2013
Messages : 19
Détails du profil
Informations personnelles :
Nom : Homme Rulx Philome Alexis
Localisation : Haïti

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

Informations forums :
Inscription : janvier 2013
Messages : 19
Points : 23
Points : 23
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
alexisleprogrammeur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2013, 00h59   #6
pythéas
Membre éclairé
 
Inscription : août 2007
Messages : 174
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 174
Points : 393
Points : 393
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...
pythéas est déconnecté   Envoyer un message privé Réponse avec citation 30
Vieux 21/02/2013, 07h57   #7
Bktero
Expert Confirmé Sénior
 
Avatar de Bktero
 
Ingénieur systèmes embarqués
Inscription : juin 2009
Messages : 1 703
Détails du profil
Informations personnelles :
Âge : 25
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Ingénieur systèmes embarqués
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2009
Messages : 1 703
Points : 4 163
Points : 4 163
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/
__________________
Si Code::Blocks vous dit undefined reference to 'socket@12', cela signifie que vous avez un problème d'édition des liens. Allez dans Projects / Build Options / Linker Settings / Add et renseigner ici les .a qui vont bien. Exemple pour les sockets : C:\Program Files\CodeBlocks\MinGW\lib\libws2_32.a

Pour les adeptes du langage SMS, allez ici et ramenez la traduction française ^^

Pour vos problèmes d'embarqué, utilisez le forum dédié !
Bktero est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 26/02/2013, 02h07   #8
alexisleprogrammeur
Membre à l'essai
 
Homme Rulx Philome Alexis
Étudiant
Inscription : janvier 2013
Messages : 19
Détails du profil
Informations personnelles :
Nom : Homme Rulx Philome Alexis
Localisation : Haïti

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

Informations forums :
Inscription : janvier 2013
Messages : 19
Points : 23
Points : 23
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...
alexisleprogrammeur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/02/2013, 02h25   #9
pythéas
Membre éclairé
 
Inscription : août 2007
Messages : 174
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 174
Points : 393
Points : 393
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
pythéas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/02/2013, 02h34   #10
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 095
Points : 11 095
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
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/02/2013, 10h07   #11
Sve@r
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 495
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 45
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 : 3 495
Points : 6 604
Points : 6 604
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 :
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);
}
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 28/02/2013, 20h37   #12
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
Salut,

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

Code :
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 :
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 :
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 01/03/2013, 01h58   #13
alexisleprogrammeur
Membre à l'essai
 
Homme Rulx Philome Alexis
Étudiant
Inscription : janvier 2013
Messages : 19
Détails du profil
Informations personnelles :
Nom : Homme Rulx Philome Alexis
Localisation : Haïti

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

Informations forums :
Inscription : janvier 2013
Messages : 19
Points : 23
Points : 23
Citation:
Envoyé par darkwall_37 Voir le message
Salut,

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

Code :
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 :
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...
alexisleprogrammeur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/03/2013, 10h42   #14
leternel
Expert Confirmé
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 185
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

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

Informations forums :
Inscription : juin 2007
Messages : 1 185
Points : 2 500
Points : 2 500
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 :
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 :
1
2
int entier = 42;
int *pointeur = &entier;
L'opération inverse est l'opérateur de déréferencement: *
Code :
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 :
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.
  • La plus sotte des questions est celle qu'on ne pose pas.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 01/03/2013, 13h54   #15
Kirilenko
Membre émérite
 
Avatar de Kirilenko
 
Homme Lucas Pesenti
Étudiant
Inscription : décembre 2011
Messages : 234
Détails du profil
Informations personnelles :
Nom : Homme Lucas Pesenti
Âge : 16
Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

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

Informations forums :
Inscription : décembre 2011
Messages : 234
Points : 859
Points : 859
Envoyer un message via MSN à Kirilenko
Bonjour,

Citation:
Envoyé par darkwall_37 Voir le message
Salut,

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

Code :
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
Kirilenko est déconnecté   Envoyer un message privé Réponse avec citation 12
Vieux 01/03/2013, 15h52   #16
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
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 :
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/03/2013, 15h55   #17
Kirilenko
Membre émérite
 
Avatar de Kirilenko
 
Homme Lucas Pesenti
Étudiant
Inscription : décembre 2011
Messages : 234
Détails du profil
Informations personnelles :
Nom : Homme Lucas Pesenti
Âge : 16
Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

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

Informations forums :
Inscription : décembre 2011
Messages : 234
Points : 859
Points : 859
Envoyer un message via MSN à Kirilenko
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
Kirilenko est déconnecté   Envoyer un message privé Réponse avec citation 21
Vieux 01/03/2013, 16h04   #18
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 095
Points : 11 095
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 ».
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 30
Vieux 01/03/2013, 16h10   #19
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
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 :
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/03/2013, 16h29   #20
Bktero
Expert Confirmé Sénior
 
Avatar de Bktero
 
Ingénieur systèmes embarqués
Inscription : juin 2009
Messages : 1 703
Détails du profil
Informations personnelles :
Âge : 25
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Ingénieur systèmes embarqués
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2009
Messages : 1 703
Points : 4 163
Points : 4 163
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).
__________________
Si Code::Blocks vous dit undefined reference to 'socket@12', cela signifie que vous avez un problème d'édition des liens. Allez dans Projects / Build Options / Linker Settings / Add et renseigner ici les .a qui vont bien. Exemple pour les sockets : C:\Program Files\CodeBlocks\MinGW\lib\libws2_32.a

Pour les adeptes du langage SMS, allez ici et ramenez la traduction française ^^

Pour vos problèmes d'embarqué, utilisez le forum dédié !
Bktero est déconnecté   Envoyer un message privé Réponse avec citation 30
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 09h48.


 
 
 
 
Partenaires

Hébergement Web