cs_davidsm
Messages postés35Date d'inscriptionlundi 6 janvier 2003StatutMembreDernière intervention12 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és455Date d'inscriptionsamedi 26 octobre 2002StatutMembreDernière intervention 6 avril 20048 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...)
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és949Date d'inscriptionmardi 2 octobre 2001StatutMembreDernière intervention 8 juillet 20061 14 févr. 2003 à 11:02
Merci de m'avoir corrigé davidsm.
cs_davidsm
Messages postés35Date d'inscriptionlundi 6 janvier 2003StatutMembreDernière intervention12 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".
cs_Kaid
Messages postés949Date d'inscriptionmardi 2 octobre 2001StatutMembreDernière intervention 8 juillet 20061 13 févr. 2003 à 22:57
davidsm: 'La' ?
cs_davidsm
Messages postés35Date d'inscriptionlundi 6 janvier 2003StatutMembreDernière intervention12 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és949Date d'inscriptionmardi 2 octobre 2001StatutMembreDernière intervention 8 juillet 20061 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és35Date d'inscriptionlundi 6 janvier 2003StatutMembreDernière intervention12 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és949Date d'inscriptionmardi 2 octobre 2001StatutMembreDernière intervention 8 juillet 20061 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és21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 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;
19 févr. 2003 à 23:38
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é.
16 févr. 2003 à 15:18
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;
}
14 févr. 2003 à 11:02
14 févr. 2003 à 10:49
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;
}
13 févr. 2003 à 22:57
13 févr. 2003 à 21:55
13 févr. 2003 à 21:10
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.
13 févr. 2003 à 20:54
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.
13 févr. 2003 à 13:15
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.
13 févr. 2003 à 00:51
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;