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

Quelques question de programmation en C

6 réponses
Avatar
PaulK
Bonsoir,

je suis un débutant en langage C, je ne réalise que quelques programmes
relativement simples, comme des « jeu du nombre mystère ».

J'aurais voulu savoir deux choses :

1 - Comment faire pour obtenir un programme en terminal (que l'on lance
depuis bash et qui n'a pas d'interface graphique) qui s'ouvre comme
Mutt, ou Emacs, c'est à dire qui prend tout le terminal quand on l'ouvre
et ce jusqu'à ce que l'on le ferme.

2 - Je voudrais enregistrer la saisie de l'utilisateur dans un buffer,
depuis une fonction void. scanf ne semble marcher que depuis main(*).
Comment puis-je faire ?

Merci bien beaucoup !

PaulK

6 réponses

Avatar
Mickaël Wolff
PaulK a écrit :

1 - Comment faire pour obtenir un programme en terminal (que l'on lance
depuis bash et qui n'a pas d'interface graphique)



A la base, l'application ne sait pas ce qu'est un terminal pas plus
qu'une fenetre graphique. En revanche, des fichiers spéciaux sont
ouverts (stdin, stdout, stderr) qui permettent de communiquer avec
l'application appelante (en l'occurence, le terminal qui lance
l'application).

qui s'ouvre comme
Mutt, ou Emacs, c'est à dire qui prend tout le terminal quand on l'ouvre
et ce jusqu'à ce que l'on le ferme.



Ce sont des programmes qui utilisent des bibliothèques telles que
ncurses. Ces bibliothèques encapsulent la communication avec le
terminal, ce qui permet de contrôler l'affichage produit par le terminal.

ncurses requiert beaucoup de rigueur pour être utilisé, c'est
pourquoi je ne penses pas que tu devrais y jeter ton enthousiasme de
débutant. :)

2 - Je voudrais enregistrer la saisie de l'utilisateur dans un buffer,
depuis une fonction void. scanf ne semble marcher que depuis main(*).
Comment puis-je faire ?


scanf est une fonction qui « fonctionne » depuis partout. Tu peux
nous donner un exemple de code ?

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
PaulK
Mickaël Wolff a écrit :
PaulK a écrit :

1 - Comment faire pour obtenir un programme en terminal (que l'on
lance depuis bash et qui n'a pas d'interface graphique)



A la base, l'application ne sait pas ce qu'est un terminal pas plus
qu'une fenetre graphique. En revanche, des fichiers spéciaux sont
ouverts (stdin, stdout, stderr) qui permettent de communiquer avec
l'application appelante (en l'occurence, le terminal qui lance
l'application).

qui s'ouvre comme Mutt, ou Emacs, c'est à dire qui prend tout le
terminal quand on l'ouvre
et ce jusqu'à ce que l'on le ferme.



Ce sont des programmes qui utilisent des bibliothèques telles que
ncurses. Ces bibliothèques encapsulent la communication avec le
terminal, ce qui permet de contrôler l'affichage produit par le terminal.

ncurses requiert beaucoup de rigueur pour être utilisé, c'est pourquoi
je ne penses pas que tu devrais y jeter ton enthousiasme de débutant. :)



D'accord. Ce n'est pas grave.

2 - Je voudrais enregistrer la saisie de l'utilisateur dans un buffer,
depuis une fonction void. scanf ne semble marcher que depuis main(*).
Comment puis-je faire ?


scanf est une fonction qui « fonctionne » depuis partout. Tu peux nous
donner un exemple de code ?


Exemple :

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

int input(void);

int main(void)
{
char abc;

scanf("%1c", &abc);

printf("scanf_main : %c", abc);

char abcde = input();


printf("scanf_input : %c", abcde);

return 0;
}

int input(void)
{
char inp = 0;

scanf("%1c", &inp);

return inp;
}

La fonction input ne me demande rien, j'ai, dans le terminal, le
résultat suivant :

:~/Documents/Programmation/lenombremystere/bash$ ./input
5
scanf_main : 5scanf_input : 0
:~/Documents/Programmation/lenombremystere/bash$

Sachant que j'ai rentré le premier 5 à la main et que pour le %c suivant
scanf_input, rien ne m'a été demandé (enchainement après l'entrée du 5) !
Avatar
Richard Delorme
Le 17/12/2009 20:46, PaulK a écrit :
Mickaël Wolff a écrit :
PaulK a écrit :

1 - Comment faire pour obtenir un programme en terminal (que l'on
lance depuis bash et qui n'a pas d'interface graphique)



A la base, l'application ne sait pas ce qu'est un terminal pas plus
qu'une fenetre graphique. En revanche, des fichiers spéciaux sont
ouverts (stdin, stdout, stderr) qui permettent de communiquer avec
l'application appelante (en l'occurence, le terminal qui lance
l'application).

qui s'ouvre comme Mutt, ou Emacs, c'est à dire qui prend tout le
terminal quand on l'ouvre
et ce jusqu'à ce que l'on le ferme.



Ce sont des programmes qui utilisent des bibliothèques telles que
ncurses. Ces bibliothèques encapsulent la communication avec le
terminal, ce qui permet de contrôler l'affichage produit par le terminal.

ncurses requiert beaucoup de rigueur pour être utilisé, c'est pourquoi
je ne penses pas que tu devrais y jeter ton enthousiasme de débutant. :)



D'accord. Ce n'est pas grave.

2 - Je voudrais enregistrer la saisie de l'utilisateur dans un
buffer, depuis une fonction void. scanf ne semble marcher que depuis
main(*).
Comment puis-je faire ?


scanf est une fonction qui « fonctionne » depuis partout. Tu peux nous
donner un exemple de code ?


Exemple :

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

int input(void);

int main(void)
{
char abc;

scanf("%1c", &abc);

printf("scanf_main : %c", abc);

char abcde = input();


printf("scanf_input : %c", abcde);

return 0;
}

int input(void)
{
char inp = 0;

scanf("%1c", &inp);

return inp;
}

La fonction input ne me demande rien, j'ai, dans le terminal, le
résultat suivant :

:~/Documents/Programmation/lenombremystere/bash$ ./input
5
scanf_main : 5scanf_input : 0
:~/Documents/Programmation/lenombremystere/bash$



Je parie que cette sortie est fausse (ce n'est pas ce que t'on programme
a affiché).

Soit tu as tapé 50[entrée] et l'affichage est :

:~/Documents/Programmation/lenombremystere/bash$ ./input
50
scanf_main : 5scanf_input :
:~/Documents/Programmation/lenombremystere/bash$

soit tu as tapé 5[entrée] et l'affichage est :
:~/Documents/Programmation/lenombremystere/bash$ ./input
5
scanf_main : 5scanf_input :
:~/Documents/Programmation/lenombremystere/bash$

Mais dans tous les cas ton programme ne peut afficher à la fois un 0 non
saisi et un retour à la ligne.

Sachant que j'ai rentré le premier 5 à la main et que pour le %c suivant
scanf_input, rien ne m'a été demandé (enchainement après l'entrée du 5) !



Non, tu as entré 5 et un retour à la ligne, soit deux caractères, les
deux scanf fonctionnent comme attendu et lisent les deux caractères.

--
Richard
Avatar
Samuel Devulder
PaulK a écrit :

1 - Comment faire pour obtenir un programme en terminal (que l'on lance
depuis bash et qui n'a pas d'interface graphique) qui s'ouvre comme
Mutt, ou Emacs, c'est à dire qui prend tout le terminal quand on l'ouvre
et ce jusqu'à ce que l'on le ferme.



==> man curses
ou man ncurses
(c'est la version moderne du précédent)

http://www.manpagez.com/man/3/ncurses/
http://web.cs.mun.ca/~rod/ncurses/ncurses.html

Si tu sais programmer et surtout si tu comprends qu'il n'y a rien de
magique et que tout est indiqué dans le man, alors tu peux faire appel à
cette librairie pour contrôler le terminal: afficher du texte à une
coordonée précise, changer les couleurs, récupérer des caractères
directement au clavier sans écho écran et sans retour à la ligne etc.

Attention pendant la mise au point d'un prog qui joue avec curses, on
arrive fréquemment à casser son terminal parce que le prog est sorti (ou
a planté) sans remettre le terminal dans son mode d'origine. Mais bon,
une fois qu'on s'est fait avoir on fait gaffe. C'est le métier qui
rentre! (on apprends de ses erreurs).


2 - Je voudrais enregistrer la saisie de l'utilisateur dans un buffer,
depuis une fonction void. scanf ne semble marcher que depuis main(*).



Ben non.. main() est une fonction/procédure comme une autre. Il n'y a
rien de magique là dessous: scanf() marche partout pareil.

sam.
Avatar
Antoine Leca
PaulK écrivit :
1 - Comment faire pour obtenir un programme en terminal (que l'on lance
depuis bash et qui n'a pas d'interface graphique) qui s'ouvre comme
Mutt, ou Emacs, c'est à dire qui prend tout le terminal quand on l'ouvre
et ce jusqu'à ce que l'on le ferme.



Il n'y a pas de méthode standard, cela dépend de l'architecture cible.
En gros, si tu as entendu parler de KDE ou de GNOME, cela sert
exactement à cela (et à quelques petites choses en plus ;-), mais la
base est à ce niveau-là).

Dans les environnements *nix/Linux en mode console (terminal),
curses/ncurses est ce qui est le plus répandu (mais pas forcément ce qui
est le plus simple à manipuler).

Les environnements DOS sont à ce niveau plus simples (parce que la
diversité à gérer est beaucoup plus réduite, il n'y a qu'un seul genre
de clavier et un seul genre d'écran, et qui plus est ses dimensions sont
souvent considérées, à tord, comme figées à 80x25); Borland avait fait
une grande partie de sa réussite à la fin des années 80 avec son
environnement <conio.h>, c'est probablement plus facile à maîtriser pour
un débutant (plus facile d'obtenir des résultats probants), quite à
passer à ncurses dès que l'on maîtrise le truc.

Le conio.h de Borland est hérité de TurboPascal ; attention, les
versions de Microsoft, de Watcom ou de DigitalMars sont plus succinctes,
en particulier ne gère pas les «fenêtres» qui limite l'affichage à une
portion de l'écran. La bibliothèque de Borland a été portée ici ou là,
en particulier vers DOS 32 bits dans DJGPP ou vers Linux (en utilisant
curses par dessous).


Antoine
Avatar
PaulK
Richard Delorme a écrit :
Le 17/12/2009 20:46, PaulK a écrit :
Mickaël Wolff a écrit :
PaulK a écrit :

1 - Comment faire pour obtenir un programme en terminal (que l'on
lance depuis bash et qui n'a pas d'interface graphique)



A la base, l'application ne sait pas ce qu'est un terminal pas plus
qu'une fenetre graphique. En revanche, des fichiers spéciaux sont
ouverts (stdin, stdout, stderr) qui permettent de communiquer avec
l'application appelante (en l'occurence, le terminal qui lance
l'application).

qui s'ouvre comme Mutt, ou Emacs, c'est à dire qui prend tout le
terminal quand on l'ouvre
et ce jusqu'à ce que l'on le ferme.



Ce sont des programmes qui utilisent des bibliothèques telles que
ncurses. Ces bibliothèques encapsulent la communication avec le
terminal, ce qui permet de contrôler l'affichage produit par le
terminal.

ncurses requiert beaucoup de rigueur pour être utilisé, c'est pourquoi
je ne penses pas que tu devrais y jeter ton enthousiasme de débutant. :)



D'accord. Ce n'est pas grave.

2 - Je voudrais enregistrer la saisie de l'utilisateur dans un
buffer, depuis une fonction void. scanf ne semble marcher que depuis
main(*).
Comment puis-je faire ?


scanf est une fonction qui « fonctionne » depuis partout. Tu peux nous
donner un exemple de code ?


Exemple :

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

int input(void);

int main(void)
{
char abc;

scanf("%1c", &abc);

printf("scanf_main : %c", abc);

char abcde = input();


printf("scanf_input : %c", abcde);

return 0;
}

int input(void)
{
char inp = 0;

scanf("%1c", &inp);

return inp;
}

La fonction input ne me demande rien, j'ai, dans le terminal, le
résultat suivant :

:~/Documents/Programmation/lenombremystere/bash$
./input
5
scanf_main : 5scanf_input : 0
:~/Documents/Programmation/lenombremystere/bash$



Je parie que cette sortie est fausse (ce n'est pas ce que t'on programme
a affiché).



Huhu, a peu de choses près, si.
J'ai juste inséré quelques retours à la ligne pour plus de lisibilité,
mais le 0 n'a pas été rentré et a bien été affiché !

Soit tu as tapé 50[entrée] et l'affichage est :

:~/Documents/Programmation/lenombremystere/bash$ ./input
50
scanf_main : 5scanf_input :
:~/Documents/Programmation/lenombremystere/bash$



Oui, c'est celui-ci !

soit tu as tapé 5[entrée] et l'affichage est :
:~/Documents/Programmation/lenombremystere/bash$ ./input
5
scanf_main : 5scanf_input :
:~/Documents/Programmation/lenombremystere/bash$

Mais dans tous les cas ton programme ne peut afficher à la fois un 0 non
saisi et un retour à la ligne.
Sachant que j'ai rentré le premier 5 à la main et que pour le %c suivant
scanf_input, rien ne m'a été demandé (enchainement après l'entrée du 5) !



Non, tu as entré 5 et un retour à la ligne, soit deux caractères, les
deux scanf fonctionnent comme attendu et lisent les deux caractères.



Désolé, j'ai un peu modifié le rendu pour plus de clarté, et je me
souviens avoir entré 50 et l'avoir corrigé en 5.

Bref, donc le 2ème scanf prend le retour à la ligne…
Comment puis-je contourner ce problème ?