Dlzlogic a écrit:Petite intervention (merci d'avance à Ampholyte de participe).
J'ai fait dernièrement une petite appli. Le but était de permettre à un jeune enfant de taper des lettres sur un clavier, naturellement sans avoir besoin de faire "enter".
Naturellement le programme permet de tester si l'enfant a tapé la bonne lettre.
Pour des raisons techniques (son père ne travaille que sous linux et sa mère que sous Mac, et moi je n'ai que Windows) c'est écrit dans un environnement indépendant de ces 3 OS.
#include
#include
#include
/* On vide stdin */
void purge(void);
/* On vérifie si c est égale à Y/y/O/o */
bool check(char c);
int main(void) {
bool loop = true;
char c = 0;
do {
fprintf(stdout, "Poursuivre (o / n) ? \n"); /* Ou printf */
scanf("%c", &c);
purge();
loop = check(c);
/* Traitement */
} while (loop);
}
void purge(void) {
int c = 0;
/* On lit stdin jusqu'à ce que l'on tombe sur EOF ou \n
* Cela permet de vider le buffer en cas de mauvaise saisie utilisateur
* (La fonction fflush n'est plus recommandée ) */
while ((c = getchar()) != '\n' && c != EOF);
}
bool check(char c) {
char verif[4 + 1] = "yYoO";
int i = 0;
for (i = 0; i On poursuit le programme.
2eme tour :
On récupère n (n précédent) => On arrete le programme.
Pour corriger ce problème, on lit stdin en entier à chaque fois. C'est pour cette raison que la fonction fgets est beaucoup mieux pour traiter la réception d'une chaine de caractère.
On peut également lire une ligne entière avec un scanf :
[CODE]
char toto[125 + 1] = {0};
/* On lit jusqu'à obtenir le \n
scanf("%[^\n]", toto); /* Mais il faut également faire attention à la taille de la chaine => sinon segfault (dépassement du buffer toto) */
[/CODE]
On peut encore pousser le vice plus loin
[CODE]
char toto[125 + 1] = {0};
/* On lit jusqu'à obtenir le \n ou 125 caractères */
scanf("%125[^\n]", toto);
[/CODE]
On peut encore faire plus compliquer, mais je te laisse lire la doc ou regarder ce lien :
[url]http://xrenault.developpez.com/tutoriels/c/scanf/#L4.3[/url]
Pour lire en temps réel, je suis tombé sur le code suivant ([url]http://stackoverflow.com/questions/1513734/problem-with-kbhitand-getch-for-linux[/url]) :
[CODE]
/* Raw mode demo */
/* See exactly what is being transmitted from the terminal. To do this
we have to be more careful. */
#include
#include
#include
#include
#include
struct termios oldtermios;
int ttyraw(int fd)
{
/* Set terminal mode as follows:
Noncanonical mode - turn off ICANON.
Turn off signal-generation (ISIG)
including BREAK character (BRKINT).
Turn off any possible preprocessing of input (IEXTEN).
Turn ECHO mode off.
Disable CR-to-NL mapping on input.
Disable input parity detection (INPCK).
Disable stripping of eighth bit on input (ISTRIP).
Disable flow control (IXON).
Use eight bit characters (CS8).
Disable parity checking (PARENB).
Disable any implementation-dependent output processing (OPOST).
One byte at a time input (MIN=1, TIME=0).
*/
struct termios newtermios;
if(tcgetattr(fd, &oldtermios) < 0)
return(-1);
newtermios = oldtermios;
newtermios.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
/* OK, why IEXTEN? If IEXTEN is on, the DISCARD character
is recognized and is not passed to the process. This
character causes output to be suspended until another
DISCARD is received. The DSUSP character for job control,
the LNEXT character that removes any special meaning of
the following character, the REPRINT character, and some
others are also in this category.
*/
newtermios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
/* If an input character arrives with the wrong parity, then INPCK
is checked. If this flag is set, then IGNPAR is checked
to see if input bytes with parity errors should be ignored.
If it shouldn't be ignored, then PARMRK determines what
character sequence the process will actually see.
When we turn off IXON, the start and stop characters can be read.
*/
newtermios.c_cflag &= ~(CSIZE | PARENB);
/* CSIZE is a mask that determines the number of bits per byte.
PARENB enables parity checking on input and parity generation
on output.
*/
newtermios.c_cflag |= CS8;
/* Set 8 bits per character. */
newtermios.c_oflag &= ~(OPOST);
/* This includes things like expanding tabs to spaces. */
newtermios.c_cc[VMIN] = 1;
newtermios.c_cc[VTIME] = 0;
/* You tell me why TCSAFLUSH. */
if(tcsetattr(fd, TCSAFLUSH, &newtermios) < 0)
return(-1);
return(0);
}
int ttyreset(int fd)
{
if(tcsetattr(fd, TCSAFLUSH, &oldtermios) < 0)
return(-1);
return(0);
}
void sigcatch(int sig)
{
ttyreset(0);
exit(0);
}
void main()
{
int i;
char c;
/* Catch the most popular signals. */
if((int) signal(SIGINT,sigcatch) < 0)
{
perror("signal");
exit(1);
}
if((int)signal(SIGQUIT,sigcatch) < 0)
{
perror("signal");
exit(1);
}
if((int) signal(SIGTERM,sigcatch) < 0)
{
perror("signal");
exit(1);
}
/* Set raw mode on stdin. */
if(ttyraw(0) < 0)
{
fprintf(stderr,"Can't go to raw mode.\n");
exit(1);
}
while( (i = read(0, &c, 1)) == 1)
{
if( (c &= 255) == 0177) /* ASCII DELETE */
break;
printf( "%o\n\r", c);
}
if(ttyreset(0) < 0)
{
fprintf(stderr, "Cannot reset terminal!\n");
exit(-1);
}
if( i < 0)
{
fprintf(stderr,"Read error.\n");
exit(-1);
}
exit(0);
}
#include
#include
/* On vide stdin */
void purge(void);
/* On vérifie si c est égale à Y/y/O/o */
bool check(char c);
int main(void) {
bool loop = true;
char c = 0;
while (loop) { /* Je sais que loop = true par l'initialisation*/
fprintf(stdout, "Poursuivre (o / n) ? \n"); /* Ou printf */
scanf("%c", &c);
purge();
loop = check(c);
/* Traitement */
}
}
void purge(void) {
int c = 0;
/* On lit stdin jusqu'à ce que l'on tombe sur EOF ou \n
* Cela permet de vider le buffer en cas de mauvaise saisie utilisateur
* (La fonction fflush n'est plus recommandée ) */
while ((c = getchar()) != '\n' && c != EOF);
}
bool check(char c) {
char verif[4 + 1] = "yYoO";
int i = 0;
for (i = 0; i < 4; i++) {
if (c == verif[i]) {
return true;
}
}
return false;
}
Dlzlogic a écrit:PS. J'ai lu le tutoriel de developpez.com. On peut regretter qu'il ne soit fait aucune allusion à la méthode habituellement conseillée, cad (f)gets puis sscanf.
#include
int main(void) {
WINDOW *w=initscr();
timeout(-1);
char c = 'O';
while(c!='N'){
c = getch();
printw ("%d %c\n", c, c);
}
endwin();
return 0;
}
gcc main.c -lncurses -o output
Rockleader a écrit:Une petite question quand au code d'ampholyte.
lorsque tu écris:
char verif[4 + 1] = "yYoO";
Pourquoi ce 4+1 ?
Etant donné que les tableaux commence à 0; j'aurais juste mis char verif[3] ou bien char verif[4-1]
Etant donné que le 4ème caractère O sera indicé par 3.
Une autre question; est il possible d'inclure avec une bibliothèque le nombre complexe i dans un calcul pour avoir un résultat; racine d'un trinôme par exemple.
J'ai tenté un simple i en ayant mis la biblio math mais le compilateur ne semble pas comprendre le i.
typedef struct COMPLEX
{
float a;
float b;
};
//et on pourra alors écrire
COMPLEX z;
z.a=partie_reelle;
z.b=partie_imaginaire;
Qu'appelles-tu "biblio math" ?J'ai tenté un simple i en ayant mis la biblio math
#include
#include
#include
#include
bool verif(char c);
int main()
{
bool continu=true;
char c=0;
while (continu)
{
/*traitement*/
printf("Voulez vous calculer une nouvelle équation (o/n)");
scanf("%c",&c);
continu=verif(c);
}
bool verif(char c)
{
char rep[2+1] ="oO";
int i = 0;
for (i = 0; i < 2; i++)
{
if (c == rep[i])
{
return true;
}
}
return false;
}
return(0);
}
Dlzlogic a écrit:L'explication est simple : le C n'admet pas les fonctions imbriquées.
Il est impossible d'imbriquer des fonctions pour la raison suivante : l'un des principes fondamentaux du C est l'allocation et la récupération d'espace mémoire.
Ceci signifie que si le programme a besoin d'une fonction, il la charge et l'exécute jusqu'à la fin, c'est à dire le return.
L'adresse de retour, c'est à lire la ligne suivant l'appel de la fonction est stocké dans la pile (stack). C'est la raison pour laquelle la récursivité est à utiliser avec parcimonie (voir une discussion il y a pas très longtemps). C'est le principe du LiFo (last in first out).
D'autre part, il ne faut jamais dire (et en tout cas pas à un futur employeur) "l'utilisateur n'a qu'à pas se tromper".
bool verif();//declaration
int main(){
verif()
}...
bool verif(){
//implementation plus tard
}
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 12 invités
Tu pars déja ?
Identification
Pas encore inscrit ?
Ou identifiez-vous :