begin process at 2012 02 09 08:15:08
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Divers

 > SAISIE CLAVIER EN C

SAISIE CLAVIER EN C


 Information sur la source

 Description

Cette source permet d faire une saisie clavier +/- sécurisée en C en évitant le scanf. Je pense qu'elle peut-être utile au débutant car je suis moi même débutant et je n'ai pas trouver de saisie propre en C

Elle gère:
la taille des entrées
le type d'entrée (long, double, avertissement)
les avertissements d'erreur
...

Je dois encore faire:
La gestion des caractères spéciaux
La gestion de la taille du tableau avec un malloc(...*sizeof(..))
Toute s vos sugesstion....

Source

  • fichier .h
  • #ifndef SAISIECLAVIER_H_INCLUDED
  • #define SAISIECLAVIER_H_INCLUDED
  • /** ENUMERATION **/
  • typedef enum TypeEntree TypeEntree;
  • enum TypeEntree {
  • NOMBRE_ENTIER,
  • NOMBRE_DECIMAL,
  • CARACTERES
  • };
  • /** FONCTIONS **/
  • void viderBuffer(void);
  • int lire(char *chaine, int longueur, int Avertissement);
  • long lireLong(int avertissement);
  • double lireDouble(int avertissement);
  • int VerificationEntier (char *Entree);
  • int VerificationDecimal(char *Entree);
  • /** AVERTISSEMENT **/
  • void Avertissement(void);
  • void AvertissementLongueur(int longueur);
  • void AvertissementType(enum TypeEntree Entree);
  • #endif // SAISIECLAVIER_H_INCLUDED
  • Fichier .c
  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <string.h>
  • #include "SaisieClavier.h"
  • //TODO: gerer dimension tableau avec malloc.....
  • /** Vide le buffer clavier **/
  • void viderBuffer(void)
  • {
  • int c = 0;
  • while (c != '\n' && c != EOF)
  • {
  • c = getchar();
  • }
  • }
  • /** LECTURE **/
  • int lire(char *chaine, int longueur, int avertissement)
  • {
  • char *positionEntree = NULL;
  • if (fgets(chaine, longueur, stdin) != NULL)
  • {
  • positionEntree = strchr(chaine, '\n');
  • if (positionEntree != NULL) // Correct toute la chaine est la
  • {
  • *positionEntree = '\0';
  • return 1;
  • }
  • else //Chaine tronquée
  • {
  • viderBuffer();
  • if (avertissement==1) AvertissementLongueur(longueur);
  • return 0;
  • }
  • }
  • else
  • {
  • viderBuffer();
  • if (avertissement==1) Avertissement();
  • return 0;
  • }
  • }
  • long lireLong(int avertissement)
  • {
  • char nombreTexte[100] = {0};
  • if (lire(nombreTexte, 100, 1))
  • {
  • if (VerificationEntier(nombreTexte)==1)
  • {
  • return strtol(nombreTexte, NULL, 10);
  • }
  • else
  • {
  • TypeEntree Entree=NOMBRE_DECIMAL;
  • if (avertissement==1)AvertissementType(Entree);
  • return 0;
  • }
  • }
  • else
  • {
  • return 0;
  • }
  • }
  • double lireDouble(int avertissement)
  • {
  • char nombreTexte[100] = {0};
  • if (lire(nombreTexte, 100, 1))
  • {
  • if (VerificationDecimal(nombreTexte)==1)
  • {
  • return strtod(nombreTexte, NULL);
  • }
  • else
  • {
  • TypeEntree Entree=NOMBRE_ENTIER;
  • if (avertissement==1)AvertissementType(Entree);
  • return 0;
  • }
  • }
  • else
  • {
  • return 0;
  • }
  • }
  • /** VERIFICATIONS ENTREE **/
  • int VerificationEntier (char *Entree) //On verifie qu'il n'y a que des chiffres
  • {
  • char caractereautorise[]="0123456789";
  • int i=0;
  • //char *test=NULL;
  • for (i=0; i<strlen(Entree); i++)//parcours de l'entrée
  • {
  • //test = strchr(caractereautorise, Entree[i]);
  • if (strchr(caractereautorise, Entree[i])==0)
  • {
  • return 0;
  • }
  • }
  • return 1;
  • }
  • int VerificationDecimal(char *Entree)//On verifie qu'il n'y a que des chiffres, un . ou ,
  • {
  • char caractereautorise[]="0123456789.,";
  • char ponctuation[]=",.";
  • int i=0, nb=0;
  • for (i=0; i<strlen(Entree); i++)//parcours de l'entrée
  • {
  • if (strchr(caractereautorise, Entree[i])==0)
  • {
  • return 0;
  • }
  • }
  • for (i=0; i<strlen(Entree);i++)//boucle pour compter les , et .
  • {
  • if (strchr(ponctuation, Entree[i])!=0)
  • nb++;
  • if (nb>1)
  • {
  • //printf("\nNombre de , ou . superieur à un");
  • return 0;
  • }
  • }
  • //Remplacement de la virgule par le point...
  • char *positionVirgule = NULL;
  • if (nb==1)
  • {
  • positionVirgule = strchr(Entree, ',');
  • *positionVirgule = '.';
  • }
  • return 1;
  • }
  • /** AVERTISSEMENT **/
  • void Avertissement(void)
  • {
  • printf ("Une erreur est survenue lors de la saissie");
  • }
  • void AvertissementLongueur(int longueur)
  • {
  • printf ("La valeur entree est trop longue (Longueur max: %d caracteres)", longueur);
  • }
  • void AvertissementType(enum TypeEntree Entree)
  • {
  • switch (Entree)
  • {
  • case (NOMBRE_ENTIER):
  • printf ("Un nombre entier est attendu:\nUniquement des chiffres");
  • break;
  • case (NOMBRE_DECIMAL):
  • printf ("Un nombre entier décimal est attendu:\nUniquement des chiffres, un point ou une virgule");
  • break;
  • case (CARACTERES):
  • printf ("La valeur que vous avez entrée ne correspond pas à ce qui est attendu");
  • break;
  • default:
  • printf ("Erreur dans le fichier %s: %d",__FILE__, __LINE__);
  • break;
  • }
  • }
fichier .h

#ifndef SAISIECLAVIER_H_INCLUDED
#define SAISIECLAVIER_H_INCLUDED

/** ENUMERATION **/
typedef enum TypeEntree TypeEntree;
enum TypeEntree {
NOMBRE_ENTIER,
NOMBRE_DECIMAL,
CARACTERES
};


/** FONCTIONS **/
void viderBuffer(void);
int lire(char *chaine, int longueur, int Avertissement);
long lireLong(int avertissement);
double lireDouble(int avertissement);

int VerificationEntier (char *Entree);
int VerificationDecimal(char *Entree);

/** AVERTISSEMENT **/
void Avertissement(void);
void AvertissementLongueur(int longueur);
void AvertissementType(enum TypeEntree Entree);

#endif // SAISIECLAVIER_H_INCLUDED


Fichier .c

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

#include "SaisieClavier.h"

//TODO: gerer dimension tableau avec malloc.....

/** Vide le buffer clavier **/
void viderBuffer(void)
{
    int c = 0;
    while (c != '\n' && c != EOF)
    {
        c = getchar();
    }
}

/** LECTURE **/
int lire(char *chaine, int longueur, int avertissement)
{
    char *positionEntree = NULL;

    if (fgets(chaine, longueur, stdin) != NULL)
    {
        positionEntree = strchr(chaine, '\n');

        if (positionEntree != NULL) // Correct toute la chaine est la
        {
            *positionEntree = '\0';
            return 1;
        }
        else //Chaine tronquée
        {
            viderBuffer();
            if (avertissement==1) AvertissementLongueur(longueur);
            return 0;
        }
    }
    else
    {
        viderBuffer();
        if (avertissement==1) Avertissement();
        return 0;
    }
}

long lireLong(int avertissement)
{
    char nombreTexte[100] = {0};

    if (lire(nombreTexte, 100, 1))
    {
        if (VerificationEntier(nombreTexte)==1)
        {
            return strtol(nombreTexte, NULL, 10);
        }
        else
        {
            TypeEntree Entree=NOMBRE_DECIMAL;
            if (avertissement==1)AvertissementType(Entree);
            return 0;
        }

    }
    else
    {
        return 0;
    }
}

double lireDouble(int avertissement)
{
    char nombreTexte[100] = {0};

    if (lire(nombreTexte, 100, 1))
    {
        if (VerificationDecimal(nombreTexte)==1)
        {
            return strtod(nombreTexte, NULL);
        }
        else
        {
            TypeEntree Entree=NOMBRE_ENTIER;
            if (avertissement==1)AvertissementType(Entree);
            return 0;
        }
    }
    else
    {
        return 0;
    }
}

/** VERIFICATIONS ENTREE **/
int VerificationEntier (char *Entree) //On verifie qu'il n'y a que des chiffres
{
    char caractereautorise[]="0123456789";

    int i=0;
    //char *test=NULL;

    for (i=0; i<strlen(Entree); i++)//parcours de l'entrée
    {
        //test = strchr(caractereautorise, Entree[i]);
        if (strchr(caractereautorise, Entree[i])==0)
        {
            return 0;
        }
    }
    return 1;
}

int VerificationDecimal(char *Entree)//On verifie qu'il n'y a que des chiffres,  un . ou ,
{
    char caractereautorise[]="0123456789.,";
    char ponctuation[]=",.";

    int i=0, nb=0;

    for (i=0; i<strlen(Entree); i++)//parcours de l'entrée
    {
        if (strchr(caractereautorise, Entree[i])==0)
        {
            return 0;
        }
    }

    for (i=0; i<strlen(Entree);i++)//boucle pour compter les , et .
    {
		if (strchr(ponctuation, Entree[i])!=0)
			nb++;
		if (nb>1)
			{
			//printf("\nNombre de , ou . superieur à un");
			return 0;
			}
    }

	//Remplacement de la virgule par le point...
	char *positionVirgule = NULL;
	if (nb==1)
		{
		positionVirgule = strchr(Entree, ',');
		*positionVirgule = '.';
		}
    return 1;
}

/** AVERTISSEMENT **/
void Avertissement(void)
{
    printf ("Une erreur est survenue lors de la saissie");
}

void AvertissementLongueur(int longueur)
{
    printf ("La valeur entree est trop longue (Longueur max: %d caracteres)", longueur);
}

void AvertissementType(enum TypeEntree Entree)
{
    switch (Entree)
    {
    case (NOMBRE_ENTIER):
                    printf ("Un nombre entier est attendu:\nUniquement des chiffres");
        break;
    case (NOMBRE_DECIMAL):
                    printf ("Un nombre entier décimal est attendu:\nUniquement des chiffres, un point ou une virgule");
        break;
    case (CARACTERES):
                    printf ("La valeur que vous avez entrée ne correspond pas à ce qui est attendu");
        break;
    default:
        printf ("Erreur dans le fichier %s: %d",__FILE__, __LINE__);
        break;
    }
}

 Conclusion

Comme je vous l'ai dit, je débute en C et veux faire profiter les gens de mes codes.

De plus, avec vos remarques, je peux avancer, corriger les erreurs d'approches, corriger ma manière de programmer,...

Donc n'hésitez pas dans vos critiques constructives, remarques, idées d'améliorations,  je n'attend que ça.


 Sources de la même categorie

Source avec Zip ÉDITEUR DE RECTANGLES EN CONSOLE par seoseo
CONVERSION DE FICHIER EN FICHIER BMP par seoseo
Source avec Zip DETECTEUR EJP par idpro
Source avec Zip Source avec une capture SHOP MANAGER CONSOLE SUR WINDOWS par antho974
Source avec Zip JOUR DE NAISSANCE par fredg19

Commentaires et avis

Commentaire de YvesB73 le 16/02/2009 21:09:29

Je suis vraiment débutant et j'aimerais savoir quel peut être l'intérêt de programmer en C alors que l'avenir serait plutôt C#
Je suis passé de C a C++ et maintenant je commence a écrire en code managé  avec VS.NET c'est un plaisir mais je regrette de ne pas être passé directement par C#

Commentaire de CharSnipeur le 16/02/2009 21:51:01

C#, .NET ... tous ça c'est du propriétaire MS !
Donc, pas portable, ni forcément maintenue longtemps (VB).
D'où l'intérêt d'apprendre le C. Le monde ne s'arrête pas là où s'arrête windows !

Commentaire de Aorimn le 16/02/2009 22:23:21

Une fonction bien pratique qui te permettrait de pas faire tout ça (même si globalement, ça m'a l'air pas mal), c'est la fonction getline().

Prototype (et includes) :
       #define _GNU_SOURCE
       #include <stdio.h>

       ssize_t getline(char **lineptr, size_t *n, FILE *stream);

Exemple d'utilisation :
       ssize_t entier_retourne = 0;
       char* ligne = NULL;
       size_t buffer = 0;

       entier_retourne = getline(&ligne, &buffer, stdin);

entier_retourne contient la longueur de la chaine de caractères ligne qui, elle, contient la saisie de l'utilisateur. buffer n'apporte pas grand chose (du moins, j'en ai jamais trouvé l'utilité...) et stdin est le fichier dans lequel getline va lire (stdin est l'entrée clavier, et aussi un fichier, pas besoin de le  définir plus tôt).

En espérant que ça t'aide pour tes futurs programmes...

p.s : la macro _GNU_SOURCE fonctionne sous windows ?


Commentaire de agparchitecture le 17/02/2009 08:21:55

Aorimn deux questions:

1. getline ne renvois q'un entier. Qu'en est-il pour des caractères ou des décimal.

2. je ne comprend pas ta ligne: #define _GNU_SOURCE
    Pourquoi definir quelque chose si elle n'est pas utilisée?

Commentaire de Aorimn le 17/02/2009 19:03:46

Agparchitecture, deux réponses :

1. Ce que renvoie getline, c'est la taille de ligne (pour reprendre mon exemple, ou la taille de *lineptr pour reprendre le manuel). Mais la chaine de caractères lue est stockée dans le char* nommé ligne (ou *lineptr...)
Autrement dit, pour afficher ce que tu as lu dans un fichier quelconque (même l'entrée standard (= le clavier)), tu fais :  puts(ligne); ou  printf(ligne); (puts() est plus optimisée il me semble...)
Avec un while, tu peux comme ça lire un fichier ligne par ligne, sans avoir peur de dépasser l'espace mémoire que tu aurais allouer avec un fgets().

2. La ligne #define _GNU_SOURCE ne me sert pas dans mon code, mais elle est nécessaire à la librairie stdio.h pour pouvoir utiliser la fonction getline().

Néanmoins, je ne suis pas sur que la macro fonctionne sous windows, et donc que la fonction getline() soit utilisable sous windows (auquel cas, ce programme peut servir ^^)

Commentaire de victorcoasne le 02/03/2009 13:41:35 7/10

Si tu te mets en standard C++ ça passe n'importe où en incluant
#include <iostream>
using namespace std;

puis tu fais un :
cin.getline(Temp, sizeof(Temp));

Pour un débutant c'est pas trop mal seulement tu réinvente la roue alors qu'en utilisant les standards avec éventuellement des vérifs sur std::fail (en standard C++), ou une autre fonction du C par exemple, on peut faire les choses simplement.

Commentaire de jean84 le 05/03/2009 06:40:39

Salut

fgets() est une fonction sécurisée que tu utilises parfaitement bien dans ton code. Le reste ne serait-il qu'un "habillage" autour de cette fonction ?

Pense à essayer de raccourcir si c'est le cas. Ton code est relativement propre mais manque peut être d'optimisation ;-) En tant que débutant j'imagine que tu souhaites faire parfaitement les choses ce que je comprend mais la je serais tenté de dire que c'est trop. Question que tu dois te poser : si demain tu as un petit projet qui nécessite une saisie utilisateur, sera tu prêt à insérer 212 lignes de codes dans ton source alors que celui n'aurait du en faire que 50 par exemple ?

Je ne dirais rien au fait de réinventer la roue, je ne l'ai fait que trop souvent et j'approuve ceux qui le font, je pense que c'est une bonne façon de comprendre le fonctionnement (sans perdre de vue l'utilisation des fonctions approuvées par la norme ANSI).

Bon courage pour la suite

++

Commentaire de agparchitecture le 05/03/2009 08:25:30

Merci pour les commentaires

Effectivement réinventer la roue permet de bien comprendre le fonctionnement et me permet de bien reflechir à l'algorithme.

Cependant, pourquoi optimiser le code si on utilise la programation modulaire: une fois créer multiple utilisation dans les programmes.

De plus comment optimiser ce code? suppression des  {} si une seule conditions?

Commentaire de YvesB73 le 06/03/2009 01:09:11

C'est effectivement la réponse que j'attendais en prêchant C#.
Avant de commencer à programmer il faut d'abord connaitre nos propres ambitions.
Devenir un grand parmi les grands ou seulement s'amuser à ce faire ses petits programmes sans prétention ou ambition.
Certes le monde ne s'arrête pas ou s'arrête Windows mais en ce qui me concerne j'étais très pressé de voir s'afficher quelque lignes dans une fenêtre et non dans une console.
Cela  dis je suis très admiratif devant ce code source, il reflet un souci de perfection et non de réinventer la roue.
Contrairement a ce que l'on peut lire de partout, je crois qu'il faut comprendre le C pour passer a C# mais sans pour autant trop délirer.
Et pour finir sur un phrase philosophique, je dirais qu'il est difficile de ce connaitre soit même sans connaitre nos ancêtres et ceci est bien à propos quand on parle de l'héritage dans la programmation orientée objet


Commentaire de agparchitecture le 06/03/2009 09:02:13

Pour répondre à yvesB73, j'ai commencer par développer avec la tecnologie dotnet en VB. (voir mon profil)

Cependant le but de mes programmes n'est pas de devenir un grand parmis les grands (l'informatique n'est pas mon boulot) mais simplement de developper des programmes qui peuvent me simplifier la vie et executer des taches répétitives dans mon travail d'architecte.

Si j'en suis venu à C et espère passer à C++ bientot, c'est plus par soucis de portabilité du code sous linux et éventuellement sous mac et également (à mon sense) une possibilité de comprendre un peu mieux ce que l'on fais. Je ne dits pas que c'est le cas avec C#, mais celui-ci nous propose presque des algorithmes tout fais. Bientot on programmera : Je veux un super programme qui fais cela et ceci et on l'aura ;-)

Commentaire de YvesB73 le 06/03/2009 17:13:55

Certes l'avenir des compilateurs c'est cela au même titre que l'on peut utiliser un éditeur HTML ou PHP pour créer un site en ayant seulement quelques notions de programmation en PHP ou HTML.
Mais n'est ce pas la volonté de MICROSOFT de s'octroyer des monopoles !!!
Alors que faut-il faire ?
Passer par là ou MICROSOFT souhaite nous faire passer, c'est-à-dire sous prétexte de concevoir des utilitaire de plus en plus performants  avec des interfaces de plus en plus ergonomique et a la porté de tous, il nous enlève toutes capacité de  maitrise d'un langage et tous cela parce que nous même nous allons par la force des choses faire preuve de paresse intellectuelle.
Ou faut il s'émanciper et  revenir à programmer en assembleur ?
La portabilité ? Oui mais comment peut on anticiper sur l'avenir.
Personnellement, je ne veux pas cracher dans la soupe, j'aime la politique de MICROSOFT car malgré cela Microsoft nous laisse le choix.
Taper 200 ou 300 lignes de code pour faire apparaitre une fenêtre sous XP ou autre ou cliquer sur projet win32 pour avoir à éviter ce laborieux  travail ?
Oui le monde ne s'arrête pas ou s'arrête Windows !!!



Commentaire de victorcoasne le 06/03/2009 23:01:42

On dérive un peu du sujet.
Sachez juste que si les Fenêtre vous semble trop compliqué ou trop long (bien qu'en 10 lignes c'est résolu) il vous reste les boîtes de dialogue.
Je vous conseille de voir ici pour un éditeur gratuit et très bien fait : http://www.resedit.net/

Commentaire de YvesB73 le 07/03/2009 19:54:16

Effectivement la conversation dérape car la première question que je me suis posé en voyant ce code, c'est la portabilité et l'avenir du C et je m'efforce de faire avaler  du C, du C++ et du code managé dans des applications console qui acceptent les extensions managées.
Du bidouillage certes mais cela dans un but : utiliser ce qu'il y à de bon dans le C.
Je vois d'ici la réponse, pourquoi utiliser un interpréteur comme le Net Framework alors qu'il serait si simple de passer outre.
La réponse qu'il me vient a l'esprit est celle-ci : Le net Framework n'est bien peut de choses aujourd'hui.
Mais demain ne serait ce pas la solution pour pouvoir en finir avec les problèmes de portabilité.
Le Net Framework serait-t-il portable au même titre que la machine virtuel Java ?
Ceci n'est bien sur que de la science fiction mais je me suis permis d'anticiper sur la pensé des développeurs de chez Microsoft
Mais ce n'est pas le sujet de ce topic !!!



 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

fgets scanf [ par abdoulax ] Bon voici mon pb !!Lorsque que j'utilise un scanf puis apr&#232;s un fgets, le fgets ne marche pas.Apr&#232;s qlq recherche je me suis rendu compte qu écriture de fichier [ par cobra176 ] je recherche le moyen d'&#233;crire sur un fichier texte les lignes que j'ai recherche.&nbsp; system("cls");printf("saisir le mot rechercher en respec fgets() fscanf() et taille du mot [ par goutbouyo ] Salut c'est encore moi ...J'ai encore un probl&#232;me :Dans un fichier j'ai soit des noms compos&#233;s ou soit des noms simples.Pour chaque nom on p Langage C (saisie de données sur fichier) [ par doggy59115 ] Bonjour &#224; tous ! Je bloque sur mon programme en langage C. Je suis novice !Je dois cr&#233;er un programme o&#249; l'on rentre : nom, pr&#233;nom programme en C [ par graminach ] on a un pb pour la question 2b!le programme ne tourne pas en boucle et affiche meme en cas de valeur correcte erreurmerci d'avancehttp://www-ipst.u-st HELP!!!! gérer les espace dans mon prog lors des questions [ par Ethylotek ] bijoursvoici le d&#233;but de mon prog :&nbsp;&nbsp;&nbsp; printf("Veuillez saisir votre nom:\n");&nbsp;&nbsp;&nbsp; scanf("%s",name);&nbsp;&nbsp;&nbs erreur [ par jekburn ] Bonjour, mon programme refuse de fonctionn&#233;, il commet une erreur m&#233;moireMerci pour votre aide#include &lt;stdio.h&gt;#include &lt;conio.h&g erreur d'application............please.help........... [ par jekburn ] #include &lt;stdio.h&gt;#include &lt;conio.h&gt;#include &lt;string.h&gt; struct enreg{&nbsp;char nom[30];&nbsp;char tel[10];}fiche; creation(){&nbsp; printf scanf [ par CCJ ] Bonjour! je debute en C++(oh non pas lui !) et bien si. donc voila mon bleme je ve afficher une varible suivit de mon texte pr&#233;f&#233;fini m&#233 La mémoire ne peut etre written.... [ par red4ever ] Bon voila je travaille sous visual .net 2003!lors de la compilation aucun probl&#232;me mais une fois mon programme lanc&#233;...En clair&nbsp;je dema


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,905 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales