Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Scandigt

47 réponses
Avatar
LMC
Bonjour,
Voici l'exercice que je tente de résoudre :
/* scandigt lit une saisie sans espaces de séparation et range les
caractères
identiques via une spécification de largeur, dans différentes variables
*/
#include <stdio.h> /* pour printf, scanf */
#include <stdlib.h>

int main(int argc, char *argv[])
{
long one, two, three, four, five;
printf("Entrez un nombre entier selon le modele \n");
printf(" abbcccddddeeeee\n");
printf("les lettres a, b, c, d, e designant\n");
printf("des chiffres identiques.\n");
scanf("%1ld %2ld %3ld %4ld %5ld\n", &one, &two, &three, &four,&five);
printf("%ld\n%ld\n%ld\n%ld\n%ld\n", one, two, three, four, five);

system("PAUSE");
return 0;

J'obtiens le résultat suivant après compilation :
Entrez un nombre entier selon le modèle
abbcccddddeeeee
les lettres a, b, c, d, e désignant
des chiffres identiques. j'appuie sur Enter et j'obtiens
122333444455555

mais je n'obtiens pas la suite qui devrait être
1
22
333
4444
55555
Merci pour toute aide.

--
@++
LMC

10 réponses

1 2 3 4 5
Avatar
espie
In article , LMC wrote:
Bonjour,
Voici l'exercice que je tente de résoudre :
/* scandigt lit une saisie sans espaces de séparation et range les
caractères
identiques via une spécification de largeur, dans différentes variables
*/
#include <stdio.h> /* pour printf, scanf */
#include <stdlib.h>

int main(int argc, char *argv[])
{
long one, two, three, four, five;
printf("Entrez un nombre entier selon le modele n");
printf(" abbcccddddeeeeen");
printf("les lettres a, b, c, d, e designantn");
printf("des chiffres identiques.n");
scanf("%1ld %2ld %3ld %4ld %5ldn", &one, &two, &three, &four,&five);
printf("%ldn%ldn%ldn%ldn%ldn", one, two, three, four, five);

system("PAUSE");
return 0;

J'obtiens le résultat suivant après compilation :
Entrez un nombre entier selon le modèle
abbcccddddeeeee
les lettres a, b, c, d, e désignant
des chiffres identiques. j'appuie sur Enter et j'obtiens
122333444455555

mais je n'obtiens pas la suite qui devrait être
1
22
333
4444
55555
Merci pour toute aide.



Chez moi, ca marche, a quelques details pres.

- il manque l'accolade finale, fais gaffe a ton couper-coller
- le system("PAUSE") est bien evidemment une idiosyncrasie windows, mais ca
c'est trivial a enlever.
- ton n a la fin du scanf va matcher un n.... et vu le fonctionnement des
entrees-sortie, ca veut dire que je suis bon pour appuyer DEUX fois sur
entrees pour que ca fonctionne.

Si je l'enleve, ca va marcher tout seul...

Si ca n'est pas le cas pour toi, ton systeme a un souci.

Pour l'explication complete du pourquoi du comment, le C a des regles un
peu complexes vis-a-vis des espaces et des retour a la ligne. En particulier,
sur la plupart des implementations, si tu ne fais pas de manip' dependant
de ton systeme, les entrees-sorties fonctionnent ligne complete par ligne
complete... d'ou le laxisme de " " dans scanf, qui matche a peu pres
n'importe quoi comme bloc de blanc, histoire de se resynchroniser facilement.
Et le fait que tres vite, comme tu as pu le constater, il faut en fournir
`un peu plus' a ton programme pour qu'il accepte de traiter les entrees.

-> En mode interactif, on se retrouve tres rapidement a faire du fgetc ou
du fgets, et a traiter le resultat avec sscanf... c'est plus simple que
de devoir contourner les problemes de tampon...
Avatar
Marc Boyer
On 2008-08-29, Marc Espie wrote:
In article , LMC wrote:
J'obtiens le résultat suivant après compilation :
Entrez un nombre entier selon le modèle
abbcccddddeeeee
les lettres a, b, c, d, e désignant
des chiffres identiques. j'appuie sur Enter et j'obtiens
122333444455555

mais je n'obtiens pas la suite qui devrait être
1
22
333
4444
55555
Merci pour toute aide.



Chez moi, ca marche, a quelques details pres.



Pareil.

- ton n a la fin du scanf va matcher un n.... et vu le fonctionnement des
entrees-sortie, ca veut dire que je suis bon pour appuyer DEUX fois sur
entrees pour que ca fonctionne.



Tiens, chez moi, ça bloque jusqu'à ce que j'envoie autre chose que
'n'...

Si je l'enleve, ca va marcher tout seul...



Pareil.

Si ca n'est pas le cas pour toi, ton systeme a un souci.



Non seulement il aurait un bouquin approximatif mais en plus
un environnement aux E/S buguées... Super...

-> En mode interactif, on se retrouve tres rapidement a faire du fgetc ou
du fgets, et a traiter le resultat avec sscanf... c'est plus simple que
de devoir contourner les problemes de tampon...



Voui. Mais comme fgets demande un buffer de taille connue, en fait,
si on veut traiter des lignes potentiellement très longues, ben, c'est
pénible.
De toute façon les E/S robustes c'est pénible. Le C se contente
de rajouter un peu de complexité en plus...

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
espie
In article ,
Marc Boyer wrote:
Voui. Mais comme fgets demande un buffer de taille connue, en fait,
si on veut traiter des lignes potentiellement très longues, ben, c'est
pénible.


Si je veux faire dans le portable, en general, je met un wrapper autour
de fgets avec un buffer remanent et du realloc.

En non portable, j'ai la chance d'etre sur un OS qui a une fonction
fgetln qui fait precisement ce qu'il faut, a savoir me donner un acces
direct a un buffer d'entree-sortie oriente ligne (a manipuler avec des
pincettes, mais ca minimise le nombre de copies).

Apres, il y a toujours lex et yacc, meme si on a souvent des surprises
quand on redige sa grammaire n'importe comment sans tenir compte du fait
que c'est interactif.

De toute façon les E/S robustes c'est pénible. Le C se contente
de rajouter un peu de complexité en plus...



Apres, je pense que plus grand monde de sense ne fait d'entrees-sorties
interactives en C directement pour un programme un peu complexe, vu
le nombre de bibliotheques existantes qui gerent ca tres bien...
Avatar
Marc Boyer
On 2008-08-29, Marc Espie wrote:
In article ,
Marc Boyer wrote:
Voui. Mais comme fgets demande un buffer de taille connue, en fait,
si on veut traiter des lignes potentiellement très longues, ben, c'est
pénible.


Si je veux faire dans le portable, en general, je met un wrapper autour
de fgets avec un buffer remanent et du realloc.



Pareil.

Apres, il y a toujours lex et yacc, meme si on a souvent des surprises
quand on redige sa grammaire n'importe comment sans tenir compte du fait
que c'est interactif.



J'imagine.

De toute façon les E/S robustes c'est pénible. Le C se contente
de rajouter un peu de complexité en plus...



Apres, je pense que plus grand monde de sense ne fait d'entrees-sorties
interactives en C directement pour un programme un peu complexe, vu
le nombre de bibliotheques existantes qui gerent ca tres bien...



Aussi.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
LMC
Bonsoir,
"Marc Espie" a écrit dans le message de news:
g9904n$d7a$
In article , LMC wrote:
Bonjour,
Voici l'exercice que je tente de résoudre :
/* scandigt lit une saisie sans espaces de séparation et range les
caractères
identiques via une spécification de largeur, dans différentes variables
*/
#include <stdio.h> /* pour printf, scanf */
#include <stdlib.h>

int main(int argc, char *argv[])
{
long one, two, three, four, five;
printf("Entrez un nombre entier selon le modele n");
printf(" abbcccddddeeeeen");
printf("les lettres a, b, c, d, e designantn");
printf("des chiffres identiques.n");
scanf("%1ld %2ld %3ld %4ld %5ldn", &one, &two, &three, &four,&five);
printf("%ldn%ldn%ldn%ldn%ldn", one, two, three, four, five);

system("PAUSE");
return 0;

J'obtiens le résultat suivant après compilation :
Entrez un nombre entier selon le modèle
abbcccddddeeeee
les lettres a, b, c, d, e désignant
des chiffres identiques. j'appuie sur Enter et j'obtiens
122333444455555

mais je n'obtiens pas la suite qui devrait être
1
22
333
4444
55555
Merci pour toute aide.



Chez moi, ca marche, a quelques details pres.

- il manque l'accolade finale, fais gaffe a ton couper-coller
- le system("PAUSE") est bien evidemment une idiosyncrasie windows, mais
ca
c'est trivial a enlever.
- ton n a la fin du scanf va matcher un n.... et vu le fonctionnement
des
entrees-sortie, ca veut dire que je suis bon pour appuyer DEUX fois sur
entrees pour que ca fonctionne.

Si je l'enleve, ca va marcher tout seul...

Si ca n'est pas le cas pour toi, ton systeme a un souci.

Pour l'explication complete du pourquoi du comment, le C a des regles un
peu complexes vis-a-vis des espaces et des retour a la ligne. En
particulier,
sur la plupart des implementations, si tu ne fais pas de manip' dependant
de ton systeme, les entrees-sorties fonctionnent ligne complete par ligne
complete... d'ou le laxisme de " " dans scanf, qui matche a peu pres
n'importe quoi comme bloc de blanc, histoire de se resynchroniser
facilement.
Et le fait que tres vite, comme tu as pu le constater, il faut en fournir
`un peu plus' a ton programme pour qu'il accepte de traiter les entrees.

-> En mode interactif, on se retrouve tres rapidement a faire du fgetc ou
du fgets, et a traiter le resultat avec sscanf... c'est plus simple que
de devoir contourner les problemes de tampon...



Grand merci pour la réponse, mais malheureusement, je n'ai rien compris. Je
suis toujours débutant.
LMC
Avatar
Mickaël Wolff
LMC a écrit :
Grand merci pour la réponse, mais malheureusement, je n'ai rien compris. Je
suis toujours débutant.



Ben en fait, ce qu'il faut comprendre c'est que scanf n'est pas un
outil destiné à interagir avec un humain. C'est un détournement
malheureux utilisé dans les exercice sur C.

Un programme compatible POSIX (ou ANSI C en fait ?) a à sa
disposition trois flux de fichiers ouverts lors de son démarrage :
stdin, stdout et stderr.

|¯| -> stdout
stdin -> | | -> stderr
¯

Comme tu dois le comprendre instinctivement, stdin est l'entrée
standard, stdout la sortie standard et stderr la sortie d'erreur standard.

Au démarrage du programme, le système va créer les liens de
communication nécessaires entre le programme appelant (ton shell
cmd.exe) et le programme invoqué. Le shell va continuer à récupérer ce
que tu lui saisie, et va le soumettre à l'entrée standard du programme
invoqué.

Les E/S standards sont des fichiers spéciaux. stdin en lecture seule,
les autres en écriture seule.

scanf équivaut à fscanf(stdin, ...)
printf équivaut à fprintf(stdout, ...)

Lorsque tu écris :

=== 8< == int get ;
scanf("%d", &get) ; // fscanf(stdin, "%d", &get) ;
=== 8< ==
scanf va se mettre en attende du fichier stdin. scanf ne réagira que
lorsque des données seront écrites dans l'entrée standard. Alors certes
il ne réagit pas à la moindre saisie, mais c'est parce que scanf attend
une fin de ligne pour extraire l'information (ici un entier).

J'espère que ça t'aidera à y voir plus claire.

(au fait, essaye de ne pas écorcher mon nom, ni mon prénom :'( )
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
LMC
Bonjour,

"Mickaël Wolff" a écrit dans le message de news:
48b8641a$0$10414$
LMC a écrit :
Grand merci pour la réponse, mais malheureusement, je n'ai rien compris.
Je suis toujours débutant.



Ben en fait, ce qu'il faut comprendre c'est que scanf n'est pas un outil
destiné à interagir avec un humain. C'est un détournement malheureux
utilisé dans les exercice sur C.



scanf n'est pas un outil destiné à interagir avec un humain ==> je suis au
tout début de C, alors il m'est difficile de comprendre cette explication. A
quoi sert scanf alors ? D'après le livre, la fonction scanf autorise la
saisie formatée de données (depuis le clavier du terminal) et on la désigne
souvent comme le pendant de printf. Il est également précisé que la
différence fondamentale entre scanf et printf réside dans la nature des
arguments manipulés.


Un programme compatible POSIX (ou ANSI C en fait ?) a à sa disposition
trois flux de fichiers ouverts lors de son démarrage : stdin, stdout et
stderr.

|¯| -> stdout
stdin -> | | -> stderr


¯

Ici, je ne comprends pas , car je n'ai rien lu à ce sujet dans le livre. Je
ne connais que #include <stdio.h>.



Comme tu dois le comprendre instinctivement, stdin est l'entrée
standard, stdout la sortie standard et stderr la sortie d'erreur standard.




voir ma réponse précédente.

Au démarrage du programme, le système va créer les liens de
communication nécessaires entre le programme appelant (ton shell cmd.exe)
et le programme invoqué. Le shell va continuer à récupérer ce que tu lui
saisie, et va le soumettre à l'entrée standard du programme invoqué.



je comprends vaguement.


Les E/S standards sont des fichiers spéciaux. stdin en lecture seule,
les autres en écriture seule.

scanf équivaut à fscanf(stdin, ...)
printf équivaut à fprintf(stdout, ...)



voir ma précédente réponse

Lorsque tu écris :

=== 8< == > int get ;
scanf("%d", &get) ; // fscanf(stdin, "%d", &get) ;
=== 8< ==


je crois qu'il est trop tôt pour ce texte.


scanf va se mettre en attende du fichier stdin. scanf ne réagira que
lorsque des données seront écrites dans l'entrée standard. Alors certes il
ne réagit pas à la moindre saisie, mais c'est parce que scanf attend une
fin de ligne pour extraire l'information (ici un entier).



je comprends très vaguement, mais pourquoi après avoir appuyé plusieurs fois
sur Enter, la fin ne vient pas. ( Les chiffres les uns en dessous des
autres)


J'espère que ça t'aidera à y voir plus claire.

(au fait, essaye de ne pas écorcher mon nom, ni mon prénom :'( )




Je ne manquerai pas car si tu devais écrire le mien !!! Serais-tu d'origine
germanique ?


--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org





--
@++
LMC
Avatar
LMC
RE,
"Mickaël Wolff" a écrit dans le message de news:
48b8641a$0$10414$

Grand merci pour la réponse.

--
@++
LMC
Avatar
Francois
LMC a écrit :

Un programme compatible POSIX (ou ANSI C en fait ?) a à sa disposition
trois flux de fichiers ouverts lors de son démarrage : stdin, stdout et
stderr.

|¯| -> stdout
stdin -> | | -> stderr


¯

Ici, je ne comprends pas , car je n'ai rien lu à ce sujet dans le livre. Je
ne connais que #include <stdio.h>.



Peut-être qu'un point de vocabulaire pourra t'aider. En tant que
débutant, j'ai buté souvent sur les termes "entrée" et "sortie". Je me
lance dans une explication. Surtout, que les experts n'hésitent pas à
corriger toutes mes imprécisions (ou faussetés).

En informatique, un "flux d'entrée" ou entrée (input en anglais), ce
sont des informations (en binaire a priori car dans un ordinateur toute
information finit en binaire) qui vont d'un périphérique de l'ordinateur
(le clavier par exemple) vers le micro processeur de l'ordinateur.

Un "flux de sortie" ou sortie (output en anglais), ce sont des
informations qui vont du micro processeur de l'ordinateur (sans doute
après traitement) vers un périphérique de l'ordinateur (l'écran ou
l'imprimante par exemple).

Quand tu exécutes un programme en C (ou d'une autre nature je pense),
trois flux sont automatiquement créés (par le système d'exploitation je
crois, mais je ne suis pas sûr). C'est que te disait Mickaël. Les trois
flux créés sont :

0) le flux d'entrée standard appelé stdin (standard input). Par défaut,
c'est un flux qui va du clavier (ça c'est le périphérique par défaut)
vers le microprocesseur pour être traités par ton programme.
Typiquement, scanf permet de récupérer des informations entrées par
l'utilisateur (toi) pour les mettre dans le flux d'entrée standard
(stdin). Dès fois, des programme ont un flux d'entrée standard vide
(quand par exemple tu ne mets pas de scanf dans ton programme).

1) le flux de sortie standard appelé stdout (standard output). Par
défaut, c'est un flux qui va du microprocesseur vers l'écran (ça c'est
le périphérique par défaut). Typiquement, print permet au programme de
mettre dans le flux d'entrée standard (stdin) tout ce que tu veux
afficher à l'écran (du genre "Bonjour tout le monde !!")

2) le flux d'erreur standard appelé stderr. C'est aussi un flux de
sortie qui va du microprocesseur vers l'écran. Il est utilisé quand il y
a des erreurs dans ton programme à son exécution. Il affiche donc des
messages d'erreur à l'écran. S'il n'y a pas d'erreur, a priori ce flux
est vide.

D'où le joli schéma qu'avait fait Mickaël :


|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯| --> stdout
| Le programme |
stdin --> |________________| --> stderr


Voilà, si j'ai dit des bêtises, je serais bien content d'avoir des
rectifications.

En espérant que ça puisse t'aider.


--
François
Avatar
LMC
Bonjour,
"Francois" a écrit dans le message de news:
48b91ac8$0$4829$
LMC a écrit :

Un programme compatible POSIX (ou ANSI C en fait ?) a à sa disposition
trois flux de fichiers ouverts lors de son démarrage : stdin, stdout et
stderr.

|¯| -> stdout
stdin -> | | -> stderr


¯

Ici, je ne comprends pas , car je n'ai rien lu à ce sujet dans le livre.
Je ne connais que #include <stdio.h>.



Peut-être qu'un point de vocabulaire pourra t'aider. En tant que débutant,
j'ai buté souvent sur les termes "entrée" et "sortie". Je me lance dans
une explication. Surtout, que les experts n'hésitent pas à corriger toutes
mes imprécisions (ou faussetés).



Merci pour cette aide.



En informatique, un "flux d'entrée" ou entrée (input en anglais), ce sont
des informations (en binaire a priori car dans un ordinateur toute
information finit en binaire) qui vont d'un périphérique de l'ordinateur
(le clavier par exemple) vers le micro processeur de l'ordinateur.

Un "flux de sortie" ou sortie (output en anglais), ce sont des
informations qui vont du micro processeur de l'ordinateur (sans doute
après traitement) vers un périphérique de l'ordinateur (l'écran ou
l'imprimante par exemple).

Quand tu exécutes un programme en C (ou d'une autre nature je pense),
trois flux sont automatiquement créés (par le système d'exploitation je
crois, mais je ne suis pas sûr). C'est que te disait Mickaël. Les trois
flux créés sont :

0) le flux d'entrée standard appelé stdin (standard input). Par défaut,
c'est un flux qui va du clavier (ça c'est le périphérique par défaut) vers
le microprocesseur pour être traités par ton programme. Typiquement, scanf
permet de récupérer des informations entrées par l'utilisateur (toi) pour
les mettre dans le flux d'entrée standard (stdin). Dès fois, des programme
ont un flux d'entrée standard vide (quand par exemple tu ne mets pas de
scanf dans ton programme).

1) le flux de sortie standard appelé stdout (standard output). Par défaut,
c'est un flux qui va du microprocesseur vers l'écran (ça c'est le
périphérique par défaut). Typiquement, print permet au programme de mettre
dans le flux d'entrée standard (stdin) tout ce que tu veux afficher à
l'écran (du genre "Bonjour tout le monde !!")

2) le flux d'erreur standard appelé stderr. C'est aussi un flux de sortie
qui va du microprocesseur vers l'écran. Il est utilisé quand il y a des
erreurs dans ton programme à son exécution. Il affiche donc des messages
d'erreur à l'écran. S'il n'y a pas d'erreur, a priori ce flux est vide.

D'où le joli schéma qu'avait fait Mickaël :


|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯| --> stdout
| Le programme |
stdin --> |________________| --> stderr


Voilà, si j'ai dit des bêtises, je serais bien content d'avoir des
rectifications.

En espérant que ça puisse t'aider.



Cela m'aide beaucoup, mais dans le cas présent, je ne vois rien à appliquer
à mon exercice.
Cela me permet de découvrir certaines particularités du langage C.
Dans mon livre, il n'y a pas trace de ces noms. J'ai stdarg.h, stddef.h,
stdio.h et stdlib.h. L'auteur précise que chaque compilateur dispose
souvent, en outre, de quelques autres headers spécifiques.
Encore merci.

--
@++
LMC


François



1 2 3 4 5