Scanf

Fermé
foobar47 - 5 janv. 2003 à 11:27
Maknash Messages postés 643 Date d'inscription lundi 10 septembre 2007 Statut Membre Dernière intervention 15 juillet 2013 - 3 mars 2009 à 09:34
Bonjour à tous,
comment faire pour autorisé la saisie des 'espaces' avec scanf !!
en langage C of course,
quand je saisi: "hello à tous", il prend :-hello

-tous
c'est génant, existe-t-il une autre fonction qui remplacerait scanf ou peut faire ceci avec scanf !???
Merci d'avance.
:)

7 réponses

Maknash Messages postés 643 Date d'inscription lundi 10 septembre 2007 Statut Membre Dernière intervention 15 juillet 2013 184
3 mars 2009 à 09:34
Ben plutôt que d'utiliser une boucle, t'utilises le masque d'affichage %*[^\n]
En gros ton scanf sera :
scanf("%*[^\n]",chaine);

Ou alors tu utilises le gets(chaine) ou fgets.

Je te mets un exemple dans un programme qui lit une chaîne de caractère ch et détermine la longueur de la chaîne avec un pointeur pt et le programme n'utilise pas de variables numériques.
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char ch[101]; // déclaration du tableau ch de type char avec possibilité d'insérer 100 caractères, on prévoit aussi 1 espace supplémentaire pour la \0
    char *pt; // déclaration du pointeur pt de type char

    scanf("%*[^\n]",ch);  //ou gets(ch); // lecture de la chaine de caractère
    //scanf ("%s",ch); // --> Mauvais car impossible d'insérer des espaces

    pt=ch; // le contenu de pt est l'adresse de la chaîne (du 1er élément)

    for(pt=ch;*pt;pt++); // boucle avec initialisation de pt à ch, faire tant que *pt est différent de 0 (car à la fin des chaînes de caractères se glisse un \0), et on incrémente pt de 1

    printf("%d",pt-ch); // affichage du nombre d'élément grâce à la soustraction de pt - ch

    return(0);
}

Par contre j'ai un petit problème avec le scanf car quand j'utilise le scanf à la place de gets ou le %s il me met tout le temps 15 -_-
6
elhoucine_add Messages postés 1 Date d'inscription samedi 8 mars 2008 Statut Membre Dernière intervention 8 mars 2008 1
8 mars 2008 à 14:18
vous voulez lire une chaine de caractere et pour cette raison en C il existe des fonctions qui traite ce genre de probleme -->la solition c'est utilser la fonction gets :example : gets(chaine) chaine peut etre un tableau de caractere ou un pointeure sur les caractrers
1
au fait, ce que j'ai ecrit plus haut provient de différentes sources, mais je ne comprend pas ce que signifient les valeurs 20 et 25, la valeur 20 doit etre la taille de mon tableau, si c'est le cas, je me suis trompé en disant que mon prog attend 50 caractére car le tab n'en contient que 20... puis le '25', je sais pas a quoi il sert...
Bref, j'ai eu une idée, et oui, ça m'arrive dés fois... ;)), dans la suite de mon prog, j'ai fais ceci:

char choix;
if (choix!=10)
scanf("%c",&choix);

mais ça ne marche que pour un caractère, peut-on le faire pour une chaine de caractéres ?? et bien non,
j'ai fais:
char key[1000];
printf("entrez votre clé de codage...");
if(key!=10)
scanf("%c",&key);
et le programme passe à la suite sans me demander de taper koi ke ce soit... :((
0
Pour la fonction malloc(memory allocation) je pense qu'il vaut mieux que tu recherches par toi meme(utilise google par exemple).
Mais si tu peux definir une longueur max de la chaine alors elle ne sert pas vraiment.

Sinon ton compilateur a raison pour la fonction gets(): en effet elle ne permet pas de limiter le nombre de caractere a mettre dans ton tableau. Ainsi si l'utilisateur depasse la taille du tableau le programme va continuera ecrire les données a la suite du tableau en effacant les donnée en memoire. (ce qui peux devenir plutot genant et de creer de gros bug).
De plus si le programme et difusé sur internet le gets() créé une faille dans le site les pirates avertis te diront qu'il s'agit de la celebre attaque "overflow"...

Mais revenons sur scanf:
le % de scanf defini le format. ainsi %s saisi une chaine de caractere alors que %c prend un seule caractére.Si tu fais
scanf("%c",&choix); c'est normal qu'il ne prenne qu'un seul caractere(qu'il met dans choix).
Dans la boucle que je te propose je saisi les caracteres un par un
en l'affectant dans tab[i] (i est incrementé a chaque boucle):
ainsi il prends le 1er caractere qu'il met dans tab[0], puis le 2eme dans tab[1], le 3eme dans tab[2]... ce qui s'apparente au gets().
L'avantage et que tu controle chaque caractere.

La fin de boucle definit par (tab[i] != 10) utilise le code ASCII du caractere entrée. Ainsi quand le caractere lu par scanf est le retour chariot la boucle se finit. Mais suivant l'OS que tu utilise ceci marche plus ou moins bien. Essaye avec 13 a la place de 10 (pour les dernieres version Window ). sinon tu peux aussi utiliser un
(tab[i] != '.') il faudra alors que tu precise que la chaine de caractere doit se finir par un point. l'important est que tu est compris que le test cherche le carcatere de fin de chaine pour arreter la boucle (a toi de choisir ce caractere par ex: '!' ou'*' ...).
tu peux aussi essayer avec le EOF.

Voila j'espere que j'ai ete clair. Si tu as d'autre question.
0
Salut Jojo,
j'ai essayé tout ce que tu as écris, mais ça ne fonctionne pas, premièrement, je ne comprend pas la fonction malloc(), ensuite, pour tab[j]!=10 ou 13 ou '.', ça ne marche pas non plus... j'ai reçu les conseil d'un de mes potes qui m'a dit que ça marcherai peut être avec : scanf("%[ azertyyuiop...];
dans le crochet, on met un espace, pui tous les caractères que l'on pourra saisir... mais ça marche pas non plus !!!
pourtant dans la suite de mon prog j'ai écrit un truc du genre: if(choix!=10)
menu();
scanf("%c",%choix);
switch (.....)
{ .....
default: if (choix!=10)
printf("blabla";
}
ce qui permet au programme de fonctionner correctement!
ce n'est donc pas une histoire de caractere, à savoir 10,13 ou un autre...
Je travaille sous Linux si ça peut te renseigner.
Si t'as pas d'autre réponses pour mon problème, je crois que je vais interdir à l'utilisateur de saisir un 'espace', mais ce serait vraiment mon dernier recourt...
j'éspère que non!
@+
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
salut foobar47,
Bon, je crois que ton probleme à assez duré...
voici le code qui te permet de saisir une chaine de caractere espace compris:

i=0;
scanf("%c",&tab[i]);
while(tab[i] != '.' && i<MAX){
i++;
scanf("%c",&tab[i]);
}

Ta chaine de caractere doit se finir par un point (tu peux mettre autre chose). A la fin de la boucle, ta chaine est stocké dans tab
d'une longueure de i-1 caractéres (le i eme est le point).
La longueur maximale de la chaine est MAX.( a toi de la definir).

Voila. compile ce programme. Ca m'etonnerais beaucoup que ca ne marche pas :-)

@+
0
Ok, ça y est, merci Jojo, ça fonctionne, mais... non, je rigole, ya pa de mais, t'es trop fort... ;))) :))))
merci beaucoup Jojo, c'est sympa d'avoir pris du temps pour m'aider, merci encore.... Si j'osais, je te demanderai si à la place du '.', on pourrait mettre un retour chariot, ce que je veux dire, c'est que dés qu'on appuye sur 'Entrée', ça passe à la suite, mais bon, je n'ose pas... :)
Je vais essayer de mon coté...
Le caractère que tu mets entre ' ', ici, le point, '.' , peut on lui attribuer son code ASCII ? si c'est le cas, on peut faire de même pour le retour chariot... pas bête, mais peut etre pas faisable !???
Bref, ceci dit, c'est du chipotage ... :) ;), c'est trés bien comme ça, quoique...
Bon, je te laisse, merci encore.
@+
foobar47
0
il y a deux maniéres de contourner le scanf("%s"

- tu peut d'abord utiliser la fonction gets() qui prend une chaine de caractére(espace compris). Mais suivant ce que tu veux faire de ton appli cette solution peut s'avérer trés risquée.(D'ailleurs le scanf("%s") aussi).

- une deuxieme solution consiste à utiliser le scanf("%c" dans une boucle de la maniere suivante:

char tab[MAX];
for(i=0; tab[i] != 10 && i<MAX ; i++;)
scanf("%c",&tab[i]);

attention! le nombre de caractére de ta chaine ne doit pas dépasser la valeur de MAX.
( si tu sais definir un tableau dynamiquement ( avec la fonction malloc) alors cette maniére est vraiment la meilleur).
-1
Jojo....... t'es trop fort !!!! :))))))))
merci beaucoup, ça me fais plaisir d'avoir une réponse, c'est hyper important en plus... merci encore! :)
Bon, je ne sais pas définir les tableaux dynamiquement, peut-etre que quelqu'un pourrat m'aider... Jojo par exemple :))
Sinon, ça doit bien être éxpliqué quelque part, enfin, si qqun a la solution pour les tableaux dynamique, je suis preneur, merci encore.
a bientôt...
0
J'ai essayé ce que tu m'as proposé jojo, j'ai défini le tableau dynamique comme suit:

char (*tab)[20];
tab = (char (*)[20])malloc(sizeof(char[25]));

puis j'ai fais ce que tu as écris, en remplaçant MAX:

for(j=0; tab[j] != 10 && j<50 ; j++)
scanf("%c",&tab[j]);

mais, il attend que je lui donne 50 caractères pour passer à la suite, or, dans mon appz, l'utilisateur doit etre restreint en nombre de caractéres à donner, mais il doit pouvoir en donner moin que la limite... c clair !? :))
ceci dit, c'est une super méthode, car le gets(), que j'avais utilisé avant, renvoy un avertissement du type: "function gets() is dangerous and should not be used" ou un truc dans le genre... merci donc à jojo qui pourra peut etre continuer dans sa lancée en corrigeant son idée...
Merci d'avance...
salutations...
:))
;))
:o)
bonne nuit
-1