Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
Ennui avec scanf
Envoyé par: nicola

J'ai un petit ennui avec scanf (non, pas le pointeur dedans).
Le dernier scanf parmi trois ne marche pas, sauf si je le fais suivre par un scanf bidon. Il me colle la valeur 0 à la variable expo si je n’ajoute pas le scanf bidon avec k.
Ce qui est bizarre, c’est que même en ajoutant à la main expo=11 (ligne commentée), expo reste nul tant que le scanf bidon n’est pas là.

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

int puissance(int N, int p, int e) // p^e modulo N
{
  int z, i;
  z=1;
  for (i=1;i<=e;i++)
  {
    z*=p;
    z%=N;
  }
  return z;
}

int main(int argc, char *argv[])
{
  srand (time (NULL));
  int base,pi,expo,k,pie;
  char message;
  int premier, deuxieme; //Premier et deuxième nombres transmis
  printf("Entrer la base ");
  scanf("%d",&base);
  printf("Entrer la perturbation ");
  scanf("%d",&pi);
  printf("Entrer l’exposant ");
  scanf("%d",&expo);
  scanf("%i",&k); // scanf bidon
//  expo=11;
  while(1)
  {
    printf("Entrer la lettre à coder ");
    scanf("%s",&message);
    k=1+(rand() % (base-1));
    premier=puissance(base,pi,k);
    printf("%i\n",expo);
    pie=puissance(base,pi,expo);
    printf("pi^e=%i\n",pie);
    deuxieme=((message-96) * puissance(base,pie,k)) % base;
    printf("Le code est (%i,%i).\n",premier,deuxieme);
  }
  return 0;
}

Oui, c’est de la cryptographie (petite).
Si quelqu’un voit ce qui se passe… Je subodore un problème avec utf8, mais pourtant quand je mets des caractères typiquement utf8 dans les printf (comme un beta), tout va bien.

--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Poste le Monday 16 April 2007 17:32:38
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: nicola

Bon, après quelques tests, le problème semble venir de gcc 4, le problème n’apparaît pas avec gcc 3.

--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Poste le Monday 16 April 2007 18:25:19
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: abgech

Il faut bien reconnaitre que scanf() est un peu une bête à chagrin.

Je me souviens avoir eu ce même type de problème il y a quelques années. Si mes souvenirs sont exacts, c'est lié avec la frappe de la touche RETURN, elle est saisie comme un caractère et il faut mettre ce caractère dans une variable.

C'est une opinion que je te donnes sous toute réserve, parce cela fait belle lurette que je n'utilise plus scanf() (trop eu d'emmerdements pour récupérer les erreurs de frappe, lettres dans une variable numérique par exemple). J'utilise fgets(), puis je décode la ligne lue avec une série de fonctions que j'ai écrites. C'est tout aussi rapide à programmer, et infiniment plus rapide à déverminer.

..................
Parce qu'il avait une clôture à utiliser, l'homme invente la propriété privée. --- F. Cavanna

Poste le Monday 16 April 2007 19:48:30
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: Fanch

je suis tout à fait d'accord avec abgech et je dirais même plus : il n'y a que fgets qui soit utilisable. Pour scanf, il faut effectivement mettre en place un système de flush mais vu que tout comme abgech je ne l'utilise jamais, je ne me souviens plus de l'implémentation standard du truc.

Par ailleurs, il me semble que scanf utilise les mêmes format string que printf ; auquel cas tu lis une chaine avec "%s", ce qui ne rentre pas (mais alors pas du tout) dans un char ...

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Monday 16 April 2007 20:37:07
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: nicola

J’ai résolu le problème en utilisant l’entrée standard via echo.

--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Poste le Tuesday 17 April 2007 07:17:52
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: nicola

Encore un ennui : dans la fonction bezout (qui calcule en fait l’inverse dans Z/baseZ de a), la variable r devient q après les calculs de tableaux avec gcc 4, et c’est q qui délire avec gcc 3. Essayer de l’appeler avec base=148 et a=5.

gcc 4 donne :
148 29 5 3
148 29 5 29
gcc 3 donne :
148 29 5 3
148 3 5 3

int bezout(int base, int a)
{
  int q,r;
  int p[1][1],pp[1][1];
  p[0][0]=1;p[0][1]=0;
  p[1][0]=0;p[1][1]=1;
  r=2;q=2;
  if (a>base)
  {
    printf("Erreur !\n");
    return 0;
  }
  else
  {
    while (r!=1)
    {
      r=base % a;
      q=(base-r)/a;printf("%i %i %i %i\n",base,q,a,r);
      pp[0][0]=p[1][0];           pp[0][1]=p[1][1]; /* Flemme de coder la multiplication de matrices 2×2 */
      pp[1][0]=p[0][0]-q*p[1][0]; pp[1][1]=p[0][1]-q*p[1][1];
      p[0][0]=pp[0][0];           p[0][1]=pp[0][1];
      p[1][0]=pp[1][0];           p[1][1]=pp[1][1];printf("%i %i %i %i\n",base,q,a,r);
      base=a;
      a=r;
    }
    return p[1][1]; /* Attention, on n’a pas calculé modulo */
  }
}

--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Poste le Tuesday 17 April 2007 10:06:27
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: Fanch

bah t'écris joyeusement n'importe où dans la mémoire :
tu déclares p[1][1] => seul p[0][0] a un sens
si tu veux taper dans du p[0][0] "jusqu'à" p[1][1], tu dois déclarer p[2][2]

en plus clair : montype var[X] te crée un tableau de X éléments de type montype indicés de 0 à X-1


gcc ne te donne pas d'erreur car en déclarant int p[1][1], pp[1][1] ; tu fais la "bonne" déclaration en ce sens que tu réserves des octets contigus (donc pas de segfault quand tu essayes d'accéder à p[1][1]) mais tu n'accèdes pas aux données auxquelles tu crois accéder.

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Tuesday 17 April 2007 11:16:36
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: nicola

Rhaaa, quel boulet.
Il faut int p[2][2],pp[2][2]; alors, et là, ça marche mieux. Merci.

--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Poste le Tuesday 17 April 2007 11:47:44
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: nicola

Ça y est, tout le bouzin marche. Merci.

--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Poste le Tuesday 17 April 2007 13:29:44
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: Fanch

t'façons, faut pas chercher midi à quatorze heures : quand les données affichées (soit comme ça, soit dans les logs) sont complètement bidon, y'a que 2 cas majeurs et hyper-fréquents :
- l'erreur de format dans la format string (genre je mets %d pour afficher un pointeur)
- un pointeur qui se prend pour indiana jones et explore la mémoire.

Si le cas devient tordu et difficile à trouver en relisant le code, une seule arme : valgrind !

have fun

------- <br />
La meilleure façon de prédire le futur, c'est de l'inventer ~ Alan Kay

Poste le Tuesday 17 April 2007 15:06:28
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: Sve@r

Citation
Fanch
et je dirais même plus : il n'y a que fgets qui soit
utilisable.
Pour scanf, il faut effectivement mettre en place un système de flush mais vu que tout comme abgech je ne l'utilise jamais, je ne me souviens plus de l'implémentation standard du truc.
Tout à fait. scanf() sur un nombre pose le problème du "return" qui n'est pas récupéré et reste dans le buffer. Une solution "batarde" consiste à, après chaque scanf("%d") de mettre un "getchar()" pour bazarder le "return" mais la meilleure solution consiste à :
- tout récupérer dans une chaîne avec "fgets()" => le buffer est vide
- extraire les nombres de la chaîne avec "sscanf()"

L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Poste le Wednesday 18 April 2007 14:32:27
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: nicola

J’ai extrait les nombres via une boucle maison, gruik mais qui marche.


--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Poste le Wednesday 18 April 2007 18:40:08
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: Sve@r

Citation
nicola
J’ai extrait les nombres via une boucle maison,
gruik mais qui marche.
Faire un programme qui "marchotte" c'est facile. Faire un programme qui marche dans toutes les conditions c'est plus dur. Par exemple, est-ce que tu peux faire "echo <les nombres> | ton_programme" ??? Ou mieux, tu places tous tes nombres dans un fichier "fic" (avec plusieurs lignes si ton programme est sensé reboucler sur plusieurs saisies) et tu fais "ton_programme <fic" ???



L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Poste le Friday 20 April 2007 09:49:43
Répondre     Citer    
Re: Ennui avec scanf
Envoyé par: nicola

Le programme marche avec echo, j’utilise l’entrée standard pour le message à décoder.
Bizarrement, il plante parfois si on a encodé avec echo "truc r" mais jamais si on a encodé avec echo 'truc r'.

--
On ne prête qu’aux riches, et on a bien raison, parce que les autres remboursent difficilement.
-+- Tristan Bernard (1866-1947) -+-

Poste le Friday 20 April 2007 11:45:05
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
Ennui avec scanf
Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons