lire touche sans appuyer entrée en C++

boubacar_de_monaco

Membre junior
1 Novembre 2005
52
0
Bonjour,

J'ai un projet à faire en C++ et le seul ordinateur que j'ai est un Mac.
Nul en informatique j'ai pris mon courage à deux mains mais j'ai l'impression qu'il y a moins d'information sur le net pou ceux qui développe sur mac.

Pourriez vous répondre à mes question s'il vous plaît?

- J'utilise Xcode. C'est bien C++ tools qu'il faut prendre lors du choix de projet?

- quels sont les différence entre développer sur C++ Linux et sur un mac?

- j'ai besoin de faire une lecture de touche sans appuyer sur entrée. J'ai trouvé un code mais qui marche avec conio.h ce qui n'existe pas sous Unix.
J'ai aussi trouvé un code qui me dit de passer le terminal en mode brut ou mode raw. J'ai mis le code mais celui ci ne marche pas.

le terminal passe en mode raw si on passe 1 en argument et 0 en cas contraire:

#include <termios.h>
#include <unistd.h>
#include "saisie_vole.h"


void mode_raw(int activer)
{
static struct termios cooked;
static int raw_actif = 0;

if (raw_actif == activer)
{
return;
}

if (activer)
{
struct termios raw;

tcgetattr(STDIN_FILENO, &cooked);

raw = cooked;
cfmakeraw(&raw);
tcsetattr(STDIN_FILENO, TCSANOW, &raw);

}
else
{
tcsetattr(STDIN_FILENO, TCSANOW, &cooked);
}

raw_actif = activer;
}



Merci de votre aide
 

ntx

Vénérable sage
Club MacG
15 Octobre 2004
12 052
370
92
- J'utilise Xcode. C'est bien C++ tools qu'il faut prendre lors du choix de projet?
oui
- quels sont les différence entre développer sur C++ Linux et sur un mac?
Pour l'apprentissage : aucune, du C++ c'est du C++ quelque soit la plate-forme, du moment que tu respectes la norme en n'utilisant que des librairies standards et que tu ne vas pas taper dans des librairies propriétaires.
C'est d'autant plus vrai entre Mac OSX et Linux si tu veux utiliser les accès au terminal Unix. Après si ton code doit aussi fonctionner sous Windows, c'est une autre affaire.
 

PA5CAL

Vétéran
Club MacG
21 Juillet 2005
9 228
597
Île-de-France
Bonjour

Voici un petit bout de code qui montre comment proc&#233;der pour recueillir les caract&#232;res isol&#233;ment sans devoir attendre qu'une ligne enti&#232;re soit saisie.

Le programme affiche les codes des caract&#232;res d&#232;s leur arriv&#233;e.
Bloc de code:
#include <stdio.h>
#include <unistd.h>
#include <termios.h>

int main() {
[COLOR="Blue"]// MODIFICATION DU FONTIONNEMENT PAR DEFAUT DU TERMINAL[/COLOR]
	[COLOR="Red"]// Lit la structure "termios" de l'entr&#233;e standard[/COLOR]
	struct termios tios;
	tcgetattr(STDIN_FILENO, &tios);

	[COLOR="Red"]// Sauve l'ancien flag "c_lflag"[/COLOR]
	tcflag_t old_c_lflag = tios.c_lflag;

	[COLOR="Red"]// Passe en mode de saisie non canonique
	// (lecture d'1 caract&#232;re &#224; la fois par d&#233;faut, car MIN=1 et TIME=0) [/COLOR]
	tios.c_lflag &= ~ICANON;
	tcsetattr(STDIN_FILENO, TCSANOW, &tios);

[COLOR="Blue"]// UTILISATION DU TERMINAL[/COLOR]
	for (;;) {
		[COLOR="Red"]// Lit un caract&#232;re sur l'entr&#233;e standard[/COLOR]
		unsigned char c;
		read(STDIN_FILENO, &c, 1);

		[COLOR="Red"]// Quitte si touche "Entr&#233;e"[/COLOR]
		if (c=='\n')
			break;

		[COLOR="Red"]// Affiche le code du caract&#232;re[/COLOR]
		printf("[&#37;02X] ", c);
		fflush(stdout);
	}

[COLOR="Blue"]// FIN[/COLOR]
	[COLOR="Red"]// Restaure l'ancien flag "c_lflag"[/COLOR]
	tios.c_lflag = old_c_lflag;
	tcsetattr(STDIN_FILENO, TCSANOW, &tios);

	return 0;
}
 

PA5CAL

Vétéran
Club MacG
21 Juillet 2005
9 228
597
Île-de-France
Bloc de code:
for (;;)

BBEEUURRKK !!!
Qu'est-ce que tu trouves &#224; y redire ?

Bon, pour les puristes, habituellement on fait :
Bloc de code:
#define forever for(;;)

...


forever {
...
}
ou bien :
Bloc de code:
#define loop for(;;)

...


loop {
...
}

Il n'emp&#234;che que &#231;a vaut mieux qu'un :
Bloc de code:
while(true) {
...
}
 
  • J’aime
Réactions: p4bl0

PA5CAL

Vétéran
Club MacG
21 Juillet 2005
9 228
597
Île-de-France
Attention. Je ne sais pas ce que &#231;a rend chez vous, mais le ~ passe tr&#232;s mal &#224; l'affichage chez moi. Pour la ligne:
Bloc de code:
	tios.c_lflag &= ~ICANON;
il faut bien lire " tios.c_lflag &= ~ICANON; ", avec un tilde, et non un signe moins !
 

boubacar_de_monaco

Membre junior
1 Novembre 2005
52
0
Merci.

J'ai une autre question:
Pouvez vous me donner des pistes(code ou sites) pour comprendre la lecture/ecriture sur fichier en C++.

Merci d'avance :)
 

boubacar_de_monaco

Membre junior
1 Novembre 2005
52
0
Merci pour la documentation mais ca m'a l'air un peu compliqué :rose:

Vous pourriez me dire ce que signifie cette sortie de programme?
"
ZeroLink: unknown symbol '__ZN7AdresseC1Ev'

location_voiture has exited due to signal 6 (SIGABRT). "

Mon programme ne renvoie pas zéro mais ceci.
 

ntx

Vénérable sage
Club MacG
15 Octobre 2004
12 052
370
92
Merci pour la documentation mais ca m'a l'air un peu compliqué
Le problème c'est que dans ton premier post, tu soulignes que tu es nul en informatique. Désolé, mais "C++" et "nul en informatique", ce n'est pas compatible. :rateau:

Clic droit sur ta cible : Get Info > Build, décoche l'option ZeroLink

PS : tu as le droit de faire une recherche avant de venir poser tes questions, on en a déjà parlé mille fois de ce zerolink. :zen:
 

boubacar_de_monaco

Membre junior
1 Novembre 2005
52
0
Bonjour

Voici un petit bout de code qui montre comment procéder pour recueillir les caractères isolément sans devoir attendre qu'une ligne entière soit saisie.

Le programme affiche les codes des caractères dès leur arrivée.
Bloc de code:
#include <stdio.h>
#include <unistd.h>
#include <termios.h>

int main() {
[COLOR="Blue"]// MODIFICATION DU FONTIONNEMENT PAR DEFAUT DU TERMINAL[/COLOR]
	[COLOR="Red"]// Lit la structure "termios" de l'entrée standard[/COLOR]
	struct termios tios;
	tcgetattr(STDIN_FILENO, &tios);

	[COLOR="Red"]// Sauve l'ancien flag "c_lflag"[/COLOR]
	tcflag_t old_c_lflag = tios.c_lflag;

	[COLOR="Red"]// Passe en mode de saisie non canonique
	// (lecture d'1 caractère à la fois par défaut, car MIN=1 et TIME=0) [/COLOR]
	tios.c_lflag &= ~ICANON;
	tcsetattr(STDIN_FILENO, TCSANOW, &tios);

[COLOR="Blue"]// UTILISATION DU TERMINAL[/COLOR]
	for (;;) {
		[COLOR="Red"]// Lit un caractère sur l'entrée standard[/COLOR]
		unsigned char c;
		read(STDIN_FILENO, &c, 1);

		[COLOR="Red"]// Quitte si touche "Entrée"[/COLOR]
		if (c=='\n')
			break;

		[COLOR="Red"]// Affiche le code du caractère[/COLOR]
		printf("[%02X] ", c);
		fflush(stdout);
	}

[COLOR="Blue"]// FIN[/COLOR]
	[COLOR="Red"]// Restaure l'ancien flag "c_lflag"[/COLOR]
	tios.c_lflag = old_c_lflag;
	tcsetattr(STDIN_FILENO, TCSANOW, &tios);

	return 0;
}
Bonjour,

J'ai essayé ton code mais, ca ne marche pas :rose:
Quand je tape "entrée" je quitte effectivement la boucle mais lorsque je presse une lettre quelconque je dois absolument valider par "entrée" sinon ça ne fonctionne pas...

Voici ce que j'ai changé dans le code

// UTILISATION DU TERMINAL

for (;;) {
// Lit un caractère sur l'entrée standard
unsigned char c;
read(STDIN_FILENO, &c, 1);

// Quitte si touche "Entrée"
if (c=='a') cout<<" vous avez tape a \n";
if (c=='b') cout<<" vous avez tape b \n";
if (c=='c') cout<<" vous avez tape c \n";
if (c=='\n')
break;

// Affiche le code du caractère
printf("[%02X] ", c);
fflush(stdout);
}


// FIN


Merci :zen:
 

PA5CAL

Vétéran
Club MacG
21 Juillet 2005
9 228
597
Île-de-France
Pourtant chez moi &#231;a fonctionne bien...

J'utilise gcc 4.0.1 pour Darwin8/PowerPC et la librairie stdc++.

Le probl&#232;me peut venir de l'affichage (printf), qui attend qu'un caract&#232;re '\n' soit envoy&#233; pour afficher une ligne enti&#232;re (c'&#233;tait la raison de mon fflush(stdout), mais peut-&#234;tre n'est-ce pas efficace dans ton cas).

Une autre possibilit&#233; est que tes options par d&#233;faut du Terminal ont &#233;t&#233; modifi&#233;es. Il faut s'assurer qu'on a toujours MIN=1 (retour apr&#232;s un caract&#232;re saisi) et TIME=0 (pas de timeout).
 

boubacar_de_monaco

Membre junior
1 Novembre 2005
52
0
J'ai mis le printf en commentaire et &#231;a n'a rien chang&#233;... :rose: :rose: :rose:

Comment on regarde les options du terminal?
je ne sais pas quel version de gcc j'utilise (j'ai acheter mon mac en novembre dernier)



Par contre si &#231;a peut aider voici ce que fais le terminal programme (ne tiens pas compte de l'affichage au dessus)

au moment ou il doit lire mon caract&#232;re j'ai entr&#233;
"kfqhslkdfhqkuefhlqkjsdhflqskhdflkqhsfkqhsfkhqskfdjhksjfhs" et puis "entr&#233;e"

Il lit bien caract&#232;re par caract&#232;re parce que au niveau du printf il me ressort les valeurs entre crochets
Le code est le m&#234;me que j'ai post&#233; 2 post plus haut:


*****************************************
** ____________________ **
** LOCATION DE VOITURES **
** **
*****************************************






e: Nouvel Emprunteur
l: Liste des Emprunteurs (chargement)

d: Edition des devis
Factures

v: Nouveau Vehicules

i: Liste des Vehicules

o: Nouvelle Location
r: Retour Location
c: Consultation des locations en cours

s: statistiques sur les v&#233;hicules les plus empruntes



q: quitter le programme
kfqhslkdfhqkuefhlqkjsdhflqskhdflkqhsfkqhsfkhqskfdjhksjfhs
[6B] [66] [71] [68] [73] [6C] [6B] [64] [66] [68] [71] [6B] [75] [65] [66] [68] [6C] [71] [6B] [6A] [73] [64] [68] [66] [6C] [71] [73] [6B] [68] [64] [66] [6C] [6B] [71] [68] [73] [66] [6B] [71] [68] [73] [66] [6B] [68] [71] [73] [6B] [66] [64] [6A] [68] [6B] [73] [6A] [66] [68] [73]

location_voiture has exited with status 0.


Cordialement
 

PA5CAL

Vétéran
Club MacG
21 Juillet 2005
9 228
597
Île-de-France
Si tu as un Mac r&#233;cent, tu dois &#234;tre sur processeur Intel.

Je pense qu'il y a une autre raison possible pour que &#231;a ne fonctionne pas: le flag ICANON n'a peut-&#234;tre pas &#233;t&#233; correctement d&#233;sactiv&#233;. Le terminal ne serait alors pas pass&#233; en mode non canonique.


Au fait, as-tu fait un copier-coller de mon code, ou bien l'as-tu recopi&#233; &#224; la main ?
 

PA5CAL

Vétéran
Club MacG
21 Juillet 2005
9 228
597
Île-de-France
Voici un extrait de l'aide concernant termios :
Bloc de code:
[B]TERMIOS(4)               BSD Kernel Interfaces Manual               TERMIOS(4)[/B]

[B]NAME[/B]
     [B]termios[/B] -- general terminal line discipline

[B]SYNOPSIS[/B]
     #include <termios.h>

  ...

[B]Noncanonical Mode Input Processing[/B]
  In noncanonical mode input processing, input bytes are not assembled into
  lines, and erase and kill processing does not occur.  The values of the
  MIN and TIME members of the [B]c_cc[/B] array are used to determine how to
  process the bytes received.

  MIN represents the minimum number of bytes that should be received when
  the read function successfully returns.  TIME is a timer of 0.1 second
  granularity that is used to time out bursty and short term data transmis-
  sions.  If MIN is greater than { MAX_INPUT}, the response to the request
  is undefined.  The four possible values for MIN and TIME and their inter-
  actions are described below.

[B]Case A: MIN > 0, TIME > 0[/B]
  ...

[B]Case B: MIN > 0, TIME = 0[/B]
  In this case, since the value of TIME is zero, the timer plays no role
  and only MIN is significant.  A pending read is not satisfied until MIN
  bytes are received (i.e., the pending read blocks until MIN bytes are
  received), or a signal is received.  A program that uses this case to
  read record-based terminal I/O may block indefinitely in the read opera-
  tion.

  ...

[B]Special Control Characters[/B]
  The special control characters values are defined by the array [B]c_cc[/B].
  This table lists the array index, the corresponding special character,
  and the system default value.  For an accurate list of the system
  defaults, consult the header file <ttydefaults.h>.

       [U] Index Name    Special Character    Default Value[/U]
        VEOF          EOF                  ^D
        VEOL          EOL                  _POSIX_VDISABLE
        VEOL2         EOL2                 _POSIX_VDISABLE
        VERASE        ERASE                ^? `\177'
        VWERASE       WERASE               ^W
        VKILL         KILL                 ^U
        VREPRINT      REPRINT              ^R
        VINTR         INTR                 ^C
        VQUIT         QUIT                 ^\\ `\34'
        VSUSP         SUSP                 ^Z
        VDSUSP        DSUSP                ^Y
        VSTART        START                ^Q
        VSTOP         STOP                 ^S
        VLNEXT        LNEXT                ^V
        VDISCARD      DISCARD              ^O
        [B]VMIN          ---                  1[/B]
        [B]VTIME         ---                  0[/B]
        VSTATUS       STATUS               ^T

  If the value of one of the changeable special control characters (see
  Special Characters) is {_POSIX_VDISABLE}, that function is disabled; that
  is, no input data is recognized as the disabled special character.  If
  ICANON is not set, the value of {_POSIX_VDISABLE} has no special meaning
  for the VMIN and VTIME entries of the [B]c_cc[/B] array.

  The initial values of the flags and control characters after open() is
  set according to the values in the header <sys/ttydefaults.h>.
Peut-&#234;tre n'avons-nous pas le m&#234;me ttydefaults.h ?
 

PA5CAL

Vétéran
Club MacG
21 Juillet 2005
9 228
597
Île-de-France
Ach !!! J'entrevois le probl&#232;me...

J'ai compil&#233; et lanc&#233; mon programme depuis l'environnement int&#233;gr&#233; de XCode... et &#231;a ne marche pas ! &#199;a me donne &#231;a:
[Session started at 2007-05-27 23:31:55 +0200.]
azerty
[61] [7A] [65] [72] [74] [79]

test has exited with status 0.
Mais en lan&#231;ant le m&#234;me programme (m&#234;me pas recompil&#233;, donc) depuis Terminal, &#231;a fonctionne bien ! &#199;a me donne &#231;a:
monmac:~ me$ cd /Users/me/test/build/Debug/
monmac:~/test/build/Debug me$ ./test
a[61] z[7A] e[65] r[72] t[74]
monmac:~/test/build/Debug me$
Bref, ce qui doit se passer, c'est que la console pr&#233;sent&#233;e par XCode n'est pas exactement &#233;quivalente au terminal !

Tu devrais r&#233;essayer ton programme depuis l'ext&#233;rieur de XCode, avec le vrai Terminal...
 

boubacar_de_monaco

Membre junior
1 Novembre 2005
52
0
un grand Merci à toi PA5CAL!

Ca marche, c'est vraiment bien. Il ne me reste plus qu'à fabriquer une fonction qui range tout ce langage barbare et que je pourrais appeler parce que c'est assez gros.

Je ne savais pas que ça pouvait etre different de lancer le terminal Xcode du Terminal Finder... :eek: :mouais:

Voila en tout cas pour ca merci beaucoup :)

Sans vouloir abuser du forum si quelqu'un peut m'expliquer ce qui ne va pas avec ce warning:

#ifdef __DEPRECATED
#warning This file includes at least one deprecated or antiquated header. \
Please consider using one of the 32 headers found in section 17.4.1.2 of the \
C++ standard. Examples include substituting the <X> header for the <X.h> \
header for C++ includes, or <iostream> instead of the deprecated header \
<iostream.h>. To disable this warning use -Wno-deprecated.
#endif


Merci encore :)