IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

[Linux] getchar() sans le return


Sujet :

C

  1. #1
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut [Linux] getchar() sans le return
    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:

    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
    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.

    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:

    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;
    }
    pfouh ! c'est galère l'introduction de code...

    char *getncharAt(int,int,int); --> colonne (x),ligne (y),nombre de caractères maximum

    Voici les tests effectués:

    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 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)
    pour le Test 2: un seul caractère non accentué et un caractère accentué

    Qu'en pensez-vous ?

  2. #2
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    avec mingw32 sur linux ça peut pas marcher?
    sinon avec Cygwin?
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    mingw32 sur linux
    ?

  4. #4
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    Citation Envoyé par Bktero Voir le message
    ?
    Reprendre les bonnes bibliothèques (ncurses), faire son programme, et faire de la compilation croisé grâce à mingw32.
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  5. #5
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    ...oui désolé je suis très occupé pour l'instant, je ne suis plus revenu sur ce code, mais d'ici peu je ferais de nouveaux tests et participerais un peu plus sur ce thread...

Discussions similaires

  1. print sans carriage return
    Par awalter1 dans le forum Général Python
    Réponses: 4
    Dernier message: 04/02/2011, 17h39
  2. Profiter d'un Linux simplement, sans prise de tête.
    Par Maxoo dans le forum Administration système
    Réponses: 21
    Dernier message: 01/08/2008, 17h32
  3. Dual boot, switcher de linux à win sans redemarrer
    Par djibril dans le forum Administration système
    Réponses: 17
    Dernier message: 23/04/2008, 12h28
  4. Installer Linux (OpenSuse) sans lecteur CD
    Par Iori Yagami dans le forum SUSE
    Réponses: 2
    Dernier message: 17/02/2008, 14h09
  5. [Portable neuf] Installer Linux CentOS sans toucher à Vista
    Par lionrouge dans le forum Installation
    Réponses: 2
    Dernier message: 02/11/2007, 08h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo