ratrapper une erreur de scanf

ratrapper une erreur de scanf - ASM - Programmation

Marsh Posté le 06-04-2008 à 21:39:36    

Salut à tous, j'ai écrit un programme en assembleur : asm gnu mon programme demande à l'utilisateur de rentrer des entiers, je les places dans un tableau et derriere j'affiche les éléments du tableau classés par ordre croissant.
Si je ne rentre que des entiers pas de problème mon programme marche parfaitement, mais si par exemple je rentre une lettre ca bug ( normal mon scanf prend un entier comme paramètre ) et il me complete mon tableau avec des 0 au lieu de continuer de demander à l'utilisateur de rentrer des entiers .
Alors je voudrais savoir, s'il y avait moyen de ratrapper l'erreur levée par le scanf via un flag par exemple ou si je suis bon pour programmer mon propre scanf qui corrigerait cette erreur.
 
merci d'avance  :hello:  

Reply

Marsh Posté le 06-04-2008 à 21:39:36   

Reply

Marsh Posté le 08-04-2008 à 18:21:21    

tu peux lire du texte et analyser la chaine saisie pour voir si elle ne contient que des entiers.
il est aussi possible de lire le flux d'entré et de l'analyser.
je dois dire que faire cela avec la syntaxe AT&T me rebuterait totalement.
essaye nasm
nasm + ld + sstrip le trio gagnant pour de la programmation en pur assembleur sans utiliser de fonction autre que les appels système.


---------------
je suis né fatigué et fait pour me reposer
Reply

Marsh Posté le 08-04-2008 à 22:15:28    

oki merci mais c'est dans le cadre de mon ecole et j'ai pas le droit au nasm ^^(asm gnu au nedit emacs, vi et ensuite on  utilise gcc pour compiler sur les tx (sun)) , sinon je vois comment le faire a partir d'une chaine de caractere mais c'est juste chiant à faire surtout pour traiter les entiers signés, alors que scanf le fait très bien quand on lui rentre des chiffres et pas n'importe quoi.

Reply

Marsh Posté le 08-04-2008 à 23:25:17    

je serais assez curieux de connaitre les raisons empéchant l'utilisation de nasm dans l'enseignement.
Il est vrai que la syntaxe AT&T est beaucoup plus efficace pour dégouter à jamais de l'assembleur.


---------------
je suis né fatigué et fait pour me reposer
Reply

Marsh Posté le 09-04-2008 à 01:12:18    

tu utilise LE scanf ou TON scanf ?

Reply

Marsh Posté le 09-04-2008 à 13:24:02    

J'utilise LE scanf, je veux recuperer un entier donc je fait un scanf(%d,eax) si je veux mettre le resultat dans eax. Et quand je rentre une lettre par exemple par il arrete l'aquisition des entiers ( s'il en reste a rentrer dans le tableau derriere ) , et met des 0 a la place.
Mais sinon je sais comment faire mon propre scanf qui va marché avec les entiers signés et relever toutes les erreurs mais c'est juste que c'est quand meme 60/70 lignes de code en asm gnu ( en ratrapant toutes les erreurs bien sur ) ( déja fait de caractere en hexa vers => nombre en binaire ) et c'est assez moche!!

Reply

Marsh Posté le 09-04-2008 à 13:45:57    

alors scanf te retourne le nombre d'élements "lus" avec réussite.
regarde la convention d'appel, normalement le int retourné par scanf se retrouve dans eax. (qui sera à 0 ou 1 dans ton cas)
 
ce qui veux aussi dire, que eax doit être "invalidé" après l'appel de scanf.

Reply

Marsh Posté le 09-04-2008 à 14:02:00    

C'est scanf() le problème, utilise fgets() + strtol().


---------------
dap.developpez.com
Reply

Marsh Posté le 09-04-2008 à 14:19:25    

autre solution, à condition de tester errno contre ERANGE.

Reply

Marsh Posté le 09-04-2008 à 17:57:46    

bjone a écrit :

alors scanf te retourne le nombre d'élements "lus" avec réussite.
regarde la convention d'appel, normalement le int retourné par scanf se retrouve dans eax. (qui sera à 0 ou 1 dans ton cas)
 
ce qui veux aussi dire, que eax doit être "invalidé" après l'appel de scanf.


 
hum pas du tout, quand je suis au debugguer l'evolution de eax il prend bien les valeurs des entiers rentrés ( ou alors j'ai rien compris a ce que tu viens de dire )
 

bjone a écrit :

autre solution, à condition de tester errno contre ERANGE.


?? tu peux traduire??
 
 
Je vais essaye avec fgets() + strtol() ( apres avoir trouvé comment les utilisés, on a vu que le scanf en cours )
 

Reply

Marsh Posté le 09-04-2008 à 17:57:46   

Reply

Marsh Posté le 09-04-2008 à 19:09:24    

debeman a écrit :


hum pas du tout, quand je suis au debugguer l'evolution de eax il prend bien les valeurs des entiers rentrés ( ou alors j'ai rien compris a ce que tu viens de dire )


Il dit ça parce que la valeur retournée par scanf() est mise dans EAX. Mais je ne comprends pas comment tu utilises scanf() :
 

debeman a écrit :

J'utilise LE scanf, je veux recuperer un entier donc je fait un scanf(%d,eax) si je veux mettre le resultat dans eax.


Normalement le deuxième paramètre l'adresse de la variable où ranger le nombre converti, donc il ne sera pas mis dans EAX. :??:
 

debeman a écrit :

Je vais essaye avec fgets() + strtol() ( apres avoir trouvé comment les utilisés, on a vu que le scanf en cours )


Un exemple ici : http://dapounet.be/dotclear/?2008/ [...] ser-strtol (en espérant que je ne me suis pas planté, ça fait quelque temps que je n'ai plus fait de C).
Le plus simple à mon avis c'est de réécrire des fonctions de saisie en C, l'utilisation de stdin et errno n'est pas portable d'un système à l'autre.


---------------
dap.developpez.com
Reply

Marsh Posté le 09-04-2008 à 21:46:59    

debeman a écrit :


 
hum pas du tout, quand je suis au debugguer l'evolution de eax il prend bien les valeurs des entiers rentrés ( ou alors j'ai rien compris a ce que tu viens de dire )
 


 

debeman a écrit :


?? tu peux traduire??
 
 
Je vais essaye avec fgets() + strtol() ( apres avoir trouvé comment les utilisés, on a vu que le scanf en cours )
 


 
quand tu appelles scanf, tu pousses bien sur la pile l'adresse du int qui va recevoir l'entier puis la chaine de formattage ?
normalement scanf doit te replacer quelque part le nombre de champs convertis, en principe dans eax.

Reply

Marsh Posté le 10-04-2008 à 15:44:41    

bjone a écrit :


 
quand tu appelles scanf, tu pousses bien sur la pile l'adresse du int qui va recevoir l'entier puis la chaine de formattage ?
normalement scanf doit te replacer quelque part le nombre de champs convertis, en principe dans eax.


 
Oui j'empile bien l'adresse qui va recevoir l'entier, j'ai di une connerie plus haut pour l'afficher derriere je fais un  
movl (%eax),%ebx par ex
je vais regarder dans quel registre est mis le nombre de champs convertis avant mon popal ^^
 
 
edit : effectivement c'est dans eax qu'on a le nombre de champs convertis, quand je rentre une lettre il reste a 0 et si c'est un entier il devient positif je vais faire un petit jump vers mon message d'erreur et voir si ca marche
merci je reviens si ca marche pas  :ange:


Message édité par debeman le 10-04-2008 à 15:48:19
Reply

Marsh Posté le 10-04-2008 à 15:55:19    

Bon le point positif c'est que je sais maintenant si l'utilisateur a rentré un entier ou non, donc je peux afficher mon message d'erreur sans problème. Par contre si je lui dit de ressaisir un entier, le scanf bloque toujours, il ne fait plus rien  :( .
Il faut faire une sorte de réinitialisation du scanf?
 
La mon programme ne plante plus mais bon il est pas très cool si jamais l'utilisateur rentre un mauvais caractère il est oblige de recommencer du début  :ange: sachant qu'il doit remplir un tableau d'entier et qu'il peut en mettre jusqu'à 1024  :ange:
 
edit : en fait non je ne ratrappe pas toutes les erreurs  :(  si par exemple je rentre 34e normalement je devrais dire à l'utilisateur que ce n'est pas un entier, %eax vaut 1 juste apres le scanf donc je ne ratrappe pas l'erreur, par contre le coup d'après il est bloqué à 0 donc si je refais un scanf l'erreur est ratrappé sinon il m'affiche juste le premier caractère du faux nombre :cry:  ( si je rentre 3548f j'ai en réalité 3 dans mon tableau  :( )

Message cité 1 fois
Message édité par debeman le 10-04-2008 à 16:12:50
Reply

Marsh Posté le 10-04-2008 à 16:09:35    

debeman a écrit :

Il faut faire une sorte de réinitialisation du scanf?


C'est parce que scanf() laisse des caractères dans le tampon et retombe dessus à chaque fois. Tu peux vider le tampon avec un code dans ce style-là :
 

Code :
  1. lireStdin:
  2.         call getchar
  3.         cmp eax, '\n'
  4.         je fin
  5.         cmp eax, EOF
  6.         jne lireStdin
  7.        
  8. fin:


 
Si tu tiens à utiliser scanf() lis ça, tu verras que c'est beaucoup plus simple de réécrire toi-même des fonctions de saisie à base de fgets() et strtol() que d'utiliser correctement scanf().


---------------
dap.developpez.com
Reply

Marsh Posté le 10-04-2008 à 16:27:48    

dap++ a écrit :


C'est parce que scanf() laisse des caractères dans le tampon et retombe dessus à chaque fois. Tu peux vider le tampon avec un code dans ce style-là :
 

Code :
  1. lireStdin:
  2.         call getchar
  3.         cmp eax, '\n'
  4.         je fin
  5.         cmp eax, EOF
  6.         jne lireStdin
  7.        
  8. fin:


 
Si tu tiens à utiliser scanf() lis ça, tu verras que c'est beaucoup plus simple de réécrire toi-même des fonctions de saisie à base de fgets() et strtol() que d'utiliser correctement scanf().


 
Le scanf à un gros avantage il gère tout seul le signe et je t'avourais que j'ai un peu la flemme d'écrire avec le fgets() et strtol()  par contre  
Je viens de lire vite fait ta page et effectivement pour récuperer les erreurs d'un scanf c'est compliqué.  
Pour le fgets() c'est bon j'ai compris comment l'utiliser et je crois que le strtol aussi en espérant qu'il fasse la conversion pour les entiers signés.
Je ferais ca demain dans le train, ou ce soir si j'ai le courage!
 

Reply

Marsh Posté le 12-04-2008 à 14:47:17    

Avec le fgets et le strtol mon programme marche
merci

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed