STL : FILTRER LE CARACTERE CLAVIER ET CONSTITUER UNE CHAINE

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 13 févr. 2003 à 00:51
cs_davidsm Messages postés 35 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 12 novembre 2004 - 19 févr. 2003 à 23:38
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/10403-stl-filtrer-le-caractere-clavier-et-constituer-une-chaine

cs_davidsm Messages postés 35 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 12 novembre 2004
19 févr. 2003 à 23:38
Pourquoi pas une classe 'Filtre'

Telle qu'elle est, il me semble qu'il vaut mieux rester sur le source amélioré avec la proposition de Kaid.

Par contre, elle est la base pour proposer des services de filtrage supplémentaires du genre :
- Le nombre de caractères à saisir
- De filtrer des valeurs pour d'autres types que les caractères : int, float ..
- --
- Dans classe Filtre, il me semble préférable de surcharger l'opérateur << plutot que (), mais c'est un peut plus compliqué.
cs_vieuxLion Messages postés 455 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 6 avril 2004 8
16 févr. 2003 à 15:18
Intéressante discussion ! je reformule
l'assembleur est intéressant... mais limité à des régions de code à optimiser aggressivement
la conclusion étant que la réutilisation est intéressante:
voici une classe Filtre réutilisant 100% de la technique ci dessus
(pas d'opérateur << pour ne pas charger...)

#include <conio.h> // getch()
#include // cout, endl
#include <string>
using namespace std;

class Filtre
{
private:
// Filtre des caracteres
string filtre_;//("+,/0129ABCW[]abez{|}");
public:
Filtre(string filtre):filtre_(filtre)
{}
bool estCorrect(char c)
{return filtre_.find(c)!=string::npos;}
operator string()
{return filtre_;}
};

int main(){
string bufferSaisie;
char carSaisi;
Filtre f("+,/0129ABCW[]abez{|}");
cout<<"Saisir, caracteres autorises (ou non): "<< (string)f<<endl;

do{
carSaisi=getch(); // Saisie d'un caractere
if (f.estCorrect(carSaisi))// le caractere appartient-il au FILTRE
bufferSaisie = bufferSaisie + carSaisi;
// Affiche le bufferSaisie
cout<<'
'<<"SAISIE :"<<bufferSaisie;
}while (carSaisi!=0x0D);
cout << endl;
return 0;
}
cs_Kaid Messages postés 949 Date d'inscription mardi 2 octobre 2001 Statut Membre Dernière intervention 8 juillet 2006 1
14 févr. 2003 à 11:02
Merci de m'avoir corrigé davidsm.
cs_davidsm Messages postés 35 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 12 novembre 2004
14 févr. 2003 à 10:49
Pour chercher si un caractère est présent dans une chaîne stockée dans un objet de type string, il faut utiliser la fonction membre de la classe string : find().

La solution proposée par de Kaid est idéale dans ce cas avec un petit aménagement pour npos :

if ( FILTRE.find(carSaisie)!=string::npos )
bufferSaisie+=carSaisie;

La fonction find() renvoie la constante string::npos lorsqu'elle atteint la fin. Dans notre cas cela traduit que carSaisie n'appartient pas au FILTRE

De manière générale :
Si on utilise un objet et que la classe dispose d'une fonction de traitement, il vaut mieux l'utiliser plutôt que d'opérer avec une fonction plus générale de la classe "algorithm".

Le PROGRAMME avec string.find():

#include <conio.h> // getch()
#include // cout, endl
#include <string>

using namespace std;

// Les caractères du FILTRE peuvent être en vrac pour find()
string FILTRE("+BCW[],/0192Aabez{|}");

int main(){
string bufferSaisie;
char carSaisie;

cout<<"Saisir, caracteres autorises : "<<FILTRE<<endl;
do{
carSaisie=getch();
if ( FILTRE.find(carSaisie)!=string::npos )
bufferSaisie+=carSaisie;
}while (carSaisie!=0x0D);

return 0;
}
cs_Kaid Messages postés 949 Date d'inscription mardi 2 octobre 2001 Statut Membre Dernière intervention 8 juillet 2006 1
13 févr. 2003 à 22:57
davidsm: 'La' ?
cs_davidsm Messages postés 35 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 12 novembre 2004
13 févr. 2003 à 21:55
La solution est mieux et plus simple car elle utilise une fonction dédiée au lieu d'utiliser une fonction générale.
cs_Kaid Messages postés 949 Date d'inscription mardi 2 octobre 2001 Statut Membre Dernière intervention 8 juillet 2006 1
13 févr. 2003 à 21:10
Autre solution:

if (FILTRE.find(carSaisie)!=npos)
bufferSaisie+=carSaisie;

Je rejoins le point de vue de davidsm, C/C++ et assembleur ont chacun leur intérêt. Pourquoi programmer en assembleur une application qui pourrait l'être en C++ ? L'optimisation oui mais dans des domaines bien précis, il n'y a plus aucun programme PC qui soit écrit complétement en assembleur, même pas les OS alors pourquoi vouloir tout programmer en asm ? Ni dans un soucis de facilité de développement, de ré-utilisation et de compréhension pour les autres.
cs_davidsm Messages postés 35 Date d'inscription lundi 6 janvier 2003 Statut Membre Dernière intervention 12 novembre 2004
13 févr. 2003 à 20:54
L'objectif du source est d'utiliser des possibilités de la STL et non de produire quelques lignes d'assembleur de moins.
Il est évident qu'un programme écrit en C et un en C++ ne s'exécutent pas de la même manière en mémoire.

Utiliser les composants standards du C++ rend les programmes portables, robustes et contribue à de qualité logiciel.

En terme de lisibilité et de facilité de programmation :
char *c = FILTRE;
while(*c) {
if(*c == carSaisie) {
bufferSaisie = bufferSaisie + carSaisie;
break;
}
c++;
}
OU
if (binary_search(FILTRE.begin(), FILTRE.end(), carSaisie))
bufferSaisie = bufferSaisie + carSaisie;

L'assembleur, le C et C++ ont chacun leur intérêt dans leur domaine.
cs_Kaid Messages postés 949 Date d'inscription mardi 2 octobre 2001 Statut Membre Dernière intervention 8 juillet 2006 1
13 févr. 2003 à 13:15
La STL (Standard Template Library) est une librarie de classes C++ template permettant de gérer les chaines de caractères, les listes, les tableaux dynamiques, les associations, ...

C'est très pratique à utiliser mais bon tu m'as l'air un grand fan de l'assembleur. La STL c'est bien mieux en terme de ré-utilisation, de lisilité, de rapidité de programmation et de concept objet que l'assembleur.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
13 févr. 2003 à 00:51
Salut,
je precise je n'ai jamais employe STL (ni autre truc). Je vois pas a quoi sert mais j'ai verife result du compilo.
Vois dessous diff code C et STL.
Tu verras, autant faire du VB, sera aussi lent et aussi lourd.
Je remplace:
char *FILTRE = ""+,/0129ABCW[]abez{|}";
en place du if (binary_search....
char *c = FILTRE;
while(*c) {
if(*c == carSaisie) {
bufferSaisie = bufferSaisie + carSaisie;
break;
}
c++;
}
Reste je ne touche pas. Compilo donne pour boucle:
call _getch
mov ecx, DWORD PTR ?FILTRE@@3PADA
mov bl, al
mov al, BYTE PTR [ecx]
test al, al
mov BYTE PTR _carSaisie$[esp+88], bl
je SHORT $L10098
npad 2
$L10097:
cmp al, bl
je SHORT $L14840
mov al, BYTE PTR [ecx+1]
inc ecx
test al, al
jne SHORT $L10097
jmp SHORT $L10098
$L14840:
; 30 : bufferSaisie = bufferSaisie + carSaisie;
VOYONS avec STL, toujours seulement if (binary_search....
call _getch
mov ecx, DWORD PTR ?FILTRE+24
cmp ecx, 16
mov esi, DWORD PTR ?FILTRE+4
mov bl, al
mov BYTE PTR _carSaisie$[esp+92], bl
mov eax, esi
jae SHORT $L15474
mov eax, OFFSET FLAT:?FILTRE+4
$L15474:
cmp ecx, 16
mov edx, DWORD PTR ?FILTRE+20
lea edi, DWORD PTR [eax+edx]
jae SHORT $L15495
mov esi, OFFSET FLAT:?FILTRE+4
$L15495:
mov ecx, edi
sub ecx, esi
cmp ecx, ebp
jle SHORT $L15909
$L15908:
mov eax, ecx
cdq
sub eax, edx
sar eax, 1
cmp BYTE PTR [esi+eax], bl
jge SHORT $L15912
mov edx, -1
sub edx, eax
lea esi, DWORD PTR [esi+eax+1]
add ecx, edx
jmp SHORT $L15913
$L15912:
mov ecx, eax
$L15913:
cmp ecx, ebp
jg SHORT $L15908
$L15909:
cmp esi, edi
je SHORT $L15990
cmp bl, BYTE PTR [esi]
jl SHORT $L15990
; 25 : bufferSaisie = bufferSaisie + carSaisie;
Rejoignez-nous