Batch Index du Forum
S’enregistrerRechercherFAQMembresGroupesConnexion
Répondre au sujet Page 1 sur 1
[TUTO] Créer une commande externe en C
Auteur Message
Répondre en citant
Message [TUTO] Créer une commande externe en C 
Bonjour, dans ce tutoriel, on va voir comment créer une commande externe en C.

I - Prérequis

- Un bon niveau en C (vous pouvez voir sur Openclassroom chapitres 1,2 et éventuellement 4 (pas 3) pour avoir l'essentiel à savoir C)
- Un editeur de code (pas spécialement un IDE, je me sert de Atom et quelquefois de notepad++ (je les trouvent plus pratiques que Codeblocks), donc c'est vous qui voyez)
- Un (ou plusieurs) compilateur C, je vous conseille :

== Pour Windows ==
+ gcc, moins sujet aux bugs, plus intuitif : http://tdm-gcc.tdragon.net/
+ tcc, quelques fois buggué, à l'énorme avantage d'avoir un résultat incroyablement compact : http://bellard.org/tcc/
+ clang qui ne fonctionne sur Windows que si vous avez Visual Studio : http://clang.llvm.org/

== Pour les *NIX (comme Linux) ==
+ gcc, globalement, vous l'avez, c'est la référence en terme de compilateurs
+ tcc, pas trop mal, mais peu intéressant comparé aux autres (il n'est plus compact)
+ clang, très efficace (rapide + rendu) et pratique, je l'utilise pour compiler darkbox

Sinon, vous pouvez très bien vous contenter de CodeBlocks pour tout ça, c'est vous qui voyez.

Dans ce tutoriel, je vais utiliser clang comme compilateur, il vous suffira simplement de renommer clang en votre compilateur que vous utilisez.

II - La compilation

Le premier soucis que l'on va avoir, c'est compiler le code en ligne de commande, pour être honnête, il n'y a rien de compliqué.

Par exemple (exemple.c) :
Code:
[lang=c]#include <stdio.h>

int main(int argc, char const *argv[])
{
    puts("Hello World !");
    return 0;
}
Et bien, pour compiler mon hello world, je vais devoir faire ça :
Code:
clang -O2 -o exemple(.exe pour Windows) exemple.c
Je rappelle de remplacer clang par le compilateur que vous utilisez.
Pour plus d'explications :
- "-O2" : active les optimisations (plus précisément, les optimisations sûres)
- "-o exemple" : Défini le fichier de sortie en "exemple"

Dans le cas où l'on doit traiter plusieurs fichiers :
Code:
clang -O2 -o exemple fichier1.c fichier2.c fichier3.c fichierN.c
Important : Il ne faut pas ajouter les fichiers .h

Globalement, c'est tout ce vous avez à savoir, il existe nottament des tutoriels pour simplifier la tâche (makefile) ou même vous même peuvent faire un fichier .bat pour automatiser cette tâche ou encore pour customiser cette compilation (la rendre plus rapide (-Ofast à la place de -O2), plus compact (-Os à la place de -O2)) etc..

III - La gestion des arguments

La gestions des arguments est relativement simple, dans notre fonction main, il y a plusieurs arguments.
Voici le prototype de la fonction main :
Code:
[lang=c]int main(int argc, char const *argv[]);
Il y a un nombre "argc", il s'agit du nombre d'arguments, il y a également argv, c'est un tableau de char*, c'est à dire, de chaîne de caractères, il s'agit des arguments passées, il faut notter que l'argument 0 est la commande elle même.

Voici un exemple ecrivant tout les arguments passées :
Code:
[lang=c]#include <stdio.h>

int main(int argc, char const *argv[])
{
    for (int i = 0; i < argc; i++)
        puts(argv[i]);

    return 0;
}


Sortie a écrit:
$ ./example arg1 arg2 arg3 arg4 arg5
./example
arg1
arg2
arg3
arg4
arg5


Si vous voulez juste avoir les arguments et pas la commande passée :
Code:
[lang=c]#include <stdio.h>

int main(int argc, char const *argv[])
{
    for (int i = 1; i < argc; i++)
        puts(argv[i]);

    return 0;
}


Voici un exemple pour afficher le caractère ASCII qui correspond à chaque argument :
Code:
[lang=c]#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    for (int i = 1; i < argc; i++)
        putchar(strtol(argv[i], NULL, 0));

    return 0;
}


Sortie a écrit:
./example 45 89 65
-YA


IV - Couleurs dans la console

Pour la gestions des couleurs, vous pouvez trés bien utiliser les fonctions de Windows comme SetConsoleTextAttribute mais je vous conseille d'utiliser du code déjà existant (qui est portable entre les plateformes) comme core.c et core.h de darkbox

Fichier brut
Code:
[lang=c]/*

 Darkbox - A Fast and Portable Console IO Server
 Copyright (c) 2016 Teddy ASTIE (TSnake41)

 All rights reserved.
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
 * Neither the name of the name of Teddy Astie (TSnake41) nor the
   names of its contributors may be used to endorse or promote products
   derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY TEDDY ASTIE AND CONTRIBUTORS ``AS IS'' AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL TEDDY ASTIE AND CONTRIBUTORS BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
 LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/
/* Darkbox Console Output Core */

#include <stdio.h>
/* #include <assert.h> */
#include "core.h"

#ifdef WIN32
#include <windows.h>

static HANDLE stdout_handle;
static CONSOLE_SCREEN_BUFFER_INFO csbi;
#else

char Ansi_Table[8] = {
    0, 4, 2, 6,
    1, 5, 3, 7,
};

#endif

#if WIN32 || __DJGPP__
#include <conio.h>
#endif

void core_init(void)
{
    #ifdef WIN32
    stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(stdout_handle, &csbi);
    #endif
}

void core_gotoxy(int x, int y)
{
    /* assert(x > -1 || y > -1); */
    if (x < 0 || y < 0)
        return;

    #ifndef WIN32
    printf("\e[%d;%df", y + 1, x + 1);
    #else
    COORD c = { x, y };
    SetConsoleCursorPosition(stdout_handle, c);
    #endif
}

void core_change_cursor_state(char state)
{
    #ifndef WIN32
    puts (
        state ?
        "\e[?25h" : /* hide */
        "\e[?25l"   /* show */
    );
    #else
    CONSOLE_CURSOR_INFO cursor;
    /* assert(GetConsoleCursorInfo(stdout_handle, &cursor)); */
    if (!GetConsoleCursorInfo(stdout_handle, &cursor))
        return;

    cursor.bVisible = (state > 0);
    SetConsoleCursorInfo(stdout_handle, &cursor);
    #endif
}

void core_clear_console(void)
{
    #ifndef WIN32
    printf("\e[2J");
    #else
    /* Based on libDos9's, Dos9_ClearConsoleScreen function
       Copyright (C) 2010-2016 Romain Garbi
    */

    COORD coordScreen = { 0, 0 };
    DWORD cCharsWritten, dwConSize;

    GetConsoleScreenBufferInfo( stdout_handle, &csbi );
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;

    FillConsoleOutputCharacter( stdout_handle, (TCHAR) ' ',
       dwConSize, coordScreen, &cCharsWritten );

    GetConsoleScreenBufferInfo( stdout_handle, &csbi );
    FillConsoleOutputAttribute( stdout_handle, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten );
    #endif

    core_gotoxy(0, 0);
}

void core_change_color(unsigned char color)
{
    #ifndef WIN32
    char bc = color & 0xF;
    char fc = color >> 4;

    printf("\e[0m\e[%s3%dm\e[%s4%dm",
        bc > 7 ? "1;" : "", Ansi_Table[bc % 8],
        fc > 7 ? "1;" : "", Ansi_Table[fc % 8]
    );
    #else
    SetConsoleTextAttribute(stdout_handle, color);
    #endif
}

void core_swritecolor(unsigned char color, const char *s)
{
    /* assert(!s); */
    if (!s)
        return;

    core_change_color(color);
    fputs(s, stdout);

    core_reset_color();
}

void core_cwritecolor(unsigned char color, int c)
{
    core_change_color(color);
    putchar(c);

    core_reset_color();
}

void core_reset_color(void)
{
    #ifndef WIN32
    fputs("\e[39m\e[49m", stdout);
    #else
    SetConsoleTextAttribute(stdout_handle, csbi.wAttributes);
    #endif
}

Fichier brut
Code:
[lang=c]/*

 Darkbox - A Fast and Portable Console IO Server
 Copyright (c) 2016 Teddy ASTIE (TSnake41)

 All rights reserved.
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
 * Neither the name of the name of Teddy Astie (TSnake41) nor the
   names of its contributors may be used to endorse or promote products
   derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY TEDDY ASTIE AND CONTRIBUTORS ``AS IS'' AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL TEDDY ASTIE AND CONTRIBUTORS BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
 LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/
#ifndef H_CORE
#define H_CORE

void core_init(void);

void core_swritecolor(unsigned char color, const char *s);
void core_cwritecolor(unsigned char color, int c);
void core_gotoxy(int x, int y);
void core_change_color(unsigned char color);
void core_change_cursor_state(char state);
void core_clear_console(void);
void core_reset_color(void);

#endif /* H_CORE */


Et pour la liste des fonctions :
Code:
[lang=c]void core_init(void)
Initialize core, n'a pas d'éffet notables sur les *NIX, doit être présent au début du code, avant l'utilisation des autres fonctions.
Code:
[lang=c]core_swritecolor(unsigned char color, const char *s)
Ecrit la chaîne de caractère s avec la couleur color.
Code:
[lang=c]core_cwritecolor(unsigned char color, int c)
Ecrit le caractère c avec la couleur color.
Code:
[lang=c]void core_gotoxy(int x, int y)
Déplace le curseur (du terminal) vers x y
Code:
[lang=c]void core_change_color(unsigned char color)
Change la couleur locale en color.
Code:
[lang=c]void core_change_cursor_state(char state)
Rend le curseur invisible si state == 0 sinon, visible.
Code:
[lang=c]void core_clear_console(void)
Vide la console.
Code:
[lang=c]void core_reset_color(void)
Redéfini la couleur en la couleur par défaut du terminal (de départ de l'execution sur Windows).

Exemple :
Code:
[lang=c]#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Inclut core.h pour pouvoir utiliser les fonctions commençant par "core_" */
#include "core.h"

int main(int argc, char const *argv[])
{
    /* Initialisation de core */
    core_init();

    /* On passe le premier argument qui est la commande entrée */
    argc--; argv++;

    /* Si le argc n'est pas un multiple de 2, on a
       pas que des paires d'arguments, donc il y a
       une erreur d'utilisation de notre commande
    */
    if ((argc % 2) == 1) {
        core_swritecolor(0x04, "ERREUR: Nombre d'arguments impair !\n");
        return -1;
    }

    /* On lit les arguments par pair dans cette boucle */
    for (int i = 0; i < argc; i+=2)
        core_swritecolor(strtol(argv[i], NULL, 16), argv[i + 1]);

    return 0;
}


Compilation :
Code:
[lang=c]clang -O2 -o example example.c core.c


Résultat :


Pour ça, vous pouvez également chercher d'autres codes/micro-librairies pour faire la même chose, je ne suis pas le seul à avoir fait ce genre de chose.

Plus tard, on va parler de l'entrée clavier + souris.



Dernière édition par TSnake41 le Lun 14 Nov 2016 - 20:50; édité 5 fois

______________________________________________________
Partager permet le savoir. Le savoir permet de partager de nouveau savoirs.
Message Publicité 
PublicitéSupprimer les publicités ?


Répondre en citant
Message [TUTO] Créer une commande externe en C 
Merci du partage Okay




______________________________________________________
Cordialement,
Hugo, qui adore programmer, jouer à Minecraft, ZT2 et FSX.
Boutons-liens :
Visiter le site web du posteur Skype
Répondre en citant
Message [TUTO] Créer une commande externe en C 
J'ai corriger quelques erreurs dans la partie 4 où le dernier code n'avait pas core_init() qui est requis pour avoir la couleur pour Windows dans core.
Egalement, je me suis arrangé pour ne plus avoir les avertissements lors de la compilation.

EDIT: J'ai corrigé un bug du nouveau code, tout marche parfaitement maintenant Very Happy




______________________________________________________
Partager permet le savoir. Le savoir permet de partager de nouveau savoirs.
Message [TUTO] Créer une commande externe en C 


Montrer les messages depuis:
Répondre au sujet Page 1 sur 1
  



Index | créer un forum | Forum gratuit d’entraide | Annuaire des forums gratuits | Signaler une violation | Conditions générales d'utilisation
Copyright 2008 - 2016 // Batch