Salutations,
Je suis actuellement en train de tester une fonction qui aurait pour but de pouvoir récupérer en mode console (oui je sais ça craint) un certain nombre de caractères entrés au clavier et dont la saisie s'achève soit lorsque le nombre de caractères maximum spécifié est atteint, soit lorsqu'on appuye sur entrée.
Cette fonction permet de faire le fameux getch() de conio.h, mais ici je travaille dans l'environnement Linux.
Voici la fonction getch() pour Linux:
J'avais lu quelque part que la libraire ncurses (que je n'ai toujours pas pris la peine de survoler) proposait quelque chose de similaire et de portable.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #ifdef LINUX int getch() { struct termios oldt, newt; struct sigaction Detournement; Detournement.sa_handler=SIG_IGN; // On ne peut pas interrompre le getch... sigaction(SIGINT,&Detournement,NULL); int ch; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // On va rétablir le comportement par défaut du CTRL-C Detournement.sa_handler=SIG_DFL; sigaction(SIGINT,&Detournement,NULL); return ch; } #endif
Pour que cela fonctionne aussi sur Windows je ne sais pas comment faire, car les fonctions sigaction() sont liées aux unix-likes (unistd.h, termios.h et signal.h).
Bon ce problème mis à part voici le code sur lequel je travaille:
pfouh ! c'est galère l'introduction de code...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 char *getncharAt(int posx,int posy,int maximum) { int index=0; int nbreCar=0; int adaptedsize=maximum; char *pTmp; char *pReturnPointer; printf("\x1b[%d;%dH",posy,posx); if(maximum>0) { pReturnPointer=(char*)malloc(sizeof(char)*maximum); pTmp=(char*)malloc(sizeof(char)*maximum); // nous utilisons un espace mémoire temporaire... sinon nous ne pourrions pas changer la taille de notre chaine de caractères avec realloc()... memset((void*)pTmp,0,maximum); } else return NULL; while(nbreCar<maximum) { *pTmp=getch(); // c'est complexe je sais... if(maximum>1) printf("%c",*pTmp); // sous Windows getch ne fait pas l'écho du caractère non plus... if(*pTmp==10 || *pTmp==27) break; // on ignore les touches de direction du clavier... et cela permet de quitter aussi avec ESC... if(*pTmp>0) { if(*pTmp!=127) // Si pas backspace (effacer) { pTmp++; index++; nbreCar++; // incrémentation du compteur pour pouvoir sortir... } else { printf("\x1b[1D"); // on retourne en arrière printf(" "); // on efface le caractère printf("\x1b[1D"); // on retourne en arrière //printf("\b"); pTmp--; // idem pour le pointeur il faut revenir une position "en arrière" index--; // il ne faut pas comptabiliser cette entrée comme étant un caractère if(*pTmp<0) // si c'est un caractère UTF8 { pTmp--; // il faut effacer le code -61 index--; // il ne faut pas comptabiliser le caractère } nbreCar--; // il ne faut pas compter cette entrée comme un caractère } } else { if(maximum==1) // cas particulier où on demande un seul caractère et que celui-ci est utf8 { pReturnPointer=(char*)realloc(pReturnPointer,sizeof(char)*3); // le code -61, le code du caractère et \0... pReturnPointer[0]=-61; pReturnPointer[1]=getch(); pReturnPointer[2]='\0'; return pReturnPointer; } if(*pTmp!=-61) nbreCar++; // bypass le code indiquant qu'on a affaire à des caractères accentués UTF8 if(maximum%2!=0) adaptedsize+=2; // si maximum n'est pas pair alors on ajoute deux caractères pour la réallocation de mémoire else adaptedsize++; // sinon on ajoute un seul caractère pReturnPointer=(char*)realloc(pReturnPointer,sizeof(char)*adaptedsize); // pour que realloc() puisse fonctionner il ne faut pas que pReturnPointer ait été modifié... pReturnPointer=pTmp-index; index++; pTmp++; if(nbreCar==maximum && (maximum%2)!=0) maximum++; // empêche de tronquer la chaine si le dernier caractère est codé en UTF8... } } *pTmp='\0'; // on insère le caractère de fin de chaine pour que cela soit propre... pReturnPointer=pTmp-index; // on retourne au début de la phrase... return pReturnPointer; }
char *getncharAt(int,int,int); --> colonne (x),ligne (y),nombre de caractères maximum
Voici les tests effectués:
pour le Test 1: chaine terminée par entrée et chaine de plus de vingt caractères (avec plein de caractères accentués dedans et notamment comme dernier caractère)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 char *strtest; strtest=getncharAt(1,1,20); printf("\nLa fonction a retourné [%s]",strtest); printf("\n ...et elle contient %d caractères selon strlen()...\n",strlen(strtest)); strtest=getnchar(1,2,1); printf("\nLa fonction a retourné [%s]",strtest); printf("\n ...et elle contient %d caractères selon strlen()...\n",strlen(strtest));
pour le Test 2: un seul caractère non accentué et un caractère accentué
Qu'en pensez-vous ?
Partager