cs_GRenard
Messages postés1662Date d'inscriptionlundi 16 septembre 2002StatutMembreDernière intervention30 juillet 2008
-
5 août 2005 à 14:03
cs_bigloo
Messages postés7Date d'inscriptionmercredi 5 octobre 2005StatutMembreDernière intervention 1 novembre 2007
-
16 oct. 2005 à 00:09
Bonjour,
J'ai ceci :
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR
lpCmdLine,
int nCmdShow)
Je souhaite obtenir les arguments un peu comme argc et argv à partir de lpCmdLine. C'est à dire en passant les arguments suivant
bonjour "test allo.txt"
je dois récupérer en premier seulement "bonjour" et ensuite "test allo.txt".
Mon programme est pour WindowsCE, donc je suis extrêmement limité,
parser par espace n'est pas une solution je crois car s'il y a des
guillemets ça ne marchera pas, et si ceux-ci sont échappé? ("test
"allo.txt")
Cette fonction ne m'est pas disponible : CommandLineToArgvW
Et je suis extrèmement limité sur l'utilisation de la STLport
cs_GRenard
Messages postés1662Date d'inscriptionlundi 16 septembre 2002StatutMembreDernière intervention30 juillet 20081 5 août 2005 à 18:20
Bon j'avais écrit un message et comme d'hab, la foutu erreur 500 me l'a perdu...
Je disais qu'on dirait que ca ne s'applique pas à ce que je veux..
peut-etre je ne comprends pas la fonction ou jsais pas quoi... je l'ai
adapté pour qu'elle fonctionne avec CE...
victorcoasne
Messages postés1101Date d'inscriptionjeudi 24 avril 2003StatutMembreDernière intervention23 juillet 20237 5 août 2005 à 22:06
Bonjour,
Voilà le code que j'ai fait sur défi lancé par magic_nono il est sous
forme d'un header .hpp c'est la forme que je conseille. Tu l'inclu et
tu appelle la fonction comme il est démontré dans l'en-tête.
Merci de laisser mon nom c'est tout ce que je demande.
Restriction : Chaque argument doit être en guillemets en sachant que
sous Windows le nom de l'executable n'est pas compris dans les
arguments de lpCmdLine.
/*
Name: detectparam.hpp
Copyright: SCV
Author: Coasne Victor
Date: 05/08/05 17:00
Description: Extraire les paramètres d'une chaîne 1D pour les mettre
dans une chaîne en 2D
Utilisation:
int nombrearguments = detectnbparam(lpCmdLine);
char**argparam = extraitparam(lpCmdLine);
for (int i= 0;i<nombrearguments;i++)
{
cout << argparam[i] << endl;
}
Attention :
Chaque argument doit être dans des guillemets
séparés
*/
int detectnbparam(char*chaineadectect)
{
int nbparam=0;
for (int i=0;i<strlen(chaineadectect);i++)
{
if (chaineadectect[i]=='"') nbparam++;
}
return nbparam/2;
}
void extraireunparam(char*chainearemplir,int premierguillemet, int dernierguillemet,
char*chaineadectect)
{
for (int i=0;i<(dernierguillemet-premierguillemet)-1;i++)
victorcoasne
Messages postés1101Date d'inscriptionjeudi 24 avril 2003StatutMembreDernière intervention23 juillet 20237 6 août 2005 à 06:55
Bonjour,
Citation : en sachant que sous Windows le nom de l'executable n'est pas compris dans les arguments de lpCmdLine
En réponse à : sauf que les elts sont soit des mots (ens de car)
soit des chaines (entre guillemet)
Complément : Comme tous les params peuvent être perso on les sépare tous.
PETIT PROGRAMME TEST POUR AIDER GRenard.
Il marche impect sous Dev-C++ :
#include
#include <stdlib.h>
using namespace std;
#include "detectparam.hpp"
int main()
{
char lpCmdLine[]=""arg1" "arg2" "arg3""arg4"";
/*
L'arg1 est séparé du 2 par un espace qui est séparé du 3 par 3 espaces
qui est séparé du 4 par rien Tous les arguments sont entre guillemets
les espaces (à l'intérieur des guillemets) sont pris en compte */
cs_bigloo
Messages postés7Date d'inscriptionmercredi 5 octobre 2005StatutMembreDernière intervention 1 novembre 2007 13 oct. 2005 à 23:48
Ton problème revient a écrire un compilateur, uniquement les parties lexicales et syntaxiques. Grosso Modo, il faut reconnaître dans une chaîne les parties entre espace si il n'y a pas eu avant un espace suivie d'un double quote et les parties entre espace suivie d'un double quote et d'un double quote suivie d'un espace comme avec les commandes windows. Pour résoudre se problème, il suffit d'écrire un automate (avantage: il termine toujours). Pour les besions de ton code, j'ai passé sous silence la partie allocation de la mémoire pour les chaînes de caractères extraites mais on peut trés bien sans passé.
char tabItem[30][20], c;
int j, k, i, etat;
etat = 0;
i = 0;
j = 0;
k = 0;
while (etat != 2) {
c = ligCommande[i];
switch (etat) {
case 0:
switch (c) {
case ' ':
case '\9':
break;
case '"':
etat = 3;
break;
case '\0' :
tabItem[j][k] = '\0';
etat = 2;
break;
default:
tabItem[j][k] = c;
k++;
etat = 1;
}
break;
case 1:
switch (c) {
case ' ':
case '\9':
tabItem[j][k] = '\0';
j++;
k = 0;
etat = 1;
break;
case '\0':
tabItem[j][k] = '\0';
etat = 2;
break;
default:
tabItem[j][k] = c;
k++;
}
break;
case 2:
break;
case 3:
switch (c) {
case '"':
etat = 4;
break;
case '\0':
tabItem[j][k] = '\0';
etat = 2;
break;
default:
tabItem[j][k] = c;
k++;
}
break;
case 4:
switch (c) {
case ' ':
case '\9':
tabItem[j][k] = '\0';
j++;
k = 0;
etat = 0;
break;
case '\0':
tabItem[j][k] = '\0';
etat = 2;
break;
default:
tabItem[j][k] = ligCommande[i-1];
k++;
tabItem[j][k] = c;
k++;
etat = 3;
}
}
i++;
}
Avec ce code tu peux extraire par exemple dans la chaîne '/DEBUG=5 "Tu es" Dans"Ton meilleur' les items suivants (en automate, on parle d'item) /DEBUG=5, Tu es, Dans"Ton meilleur. Le gateau sur la cerise, c'est qu'il n'a aucunement besion d'optimiser le code car les compilateurs modernes l'optimise facilement, d'une part. D'autre part, il est trés difficile de débugger une tel structure de programme si on s'amuse à l'optimiser soi-même. Dans ce code, la tabulation est considérée comme un espace.
L'intéret majeur d'un tel code, c'est qu'il est facilement implémentable dans tout compilateur C/C++ sans demandé de resource particulaire.
victorcoasne
Messages postés1101Date d'inscriptionjeudi 24 avril 2003StatutMembreDernière intervention23 juillet 20237 14 oct. 2005 à 23:24
Bonjour,
J'ai pas tout compris ce que tu dis mais je vois pas ce que tu reproche
à mon alocation dynaique ? et aussi tu as des compilateurs avec
presques pas de lignes toi !
C'est quoi ton compilo ?
J'ai pas trop compris l'histoire de la tabulation qui est présente dans mon code.
cs_bigloo
Messages postés7Date d'inscriptionmercredi 5 octobre 2005StatutMembreDernière intervention 1 novembre 2007 15 oct. 2005 à 09:06
Bonjour,
Mon compilo dépend du travail que je fais, en voici une liste cc (UNIX), gcc (UNIX), Dev-C++ (Win), FPC (Win), Lua (Prog Parralléle de typage C) et LeLisp. Je ne reproche rien à ton code, il fonctionne et en générale c'est ce qu'on demande à un code. Maintenant, il faut faire un automate et je maintient (Je suis un peu tête de turque).
Je n'ai rien à redire sur ton attribution de mémoire dynamique car moi-même j'en fais de manière déguisée. Quand on écrit char s[n]; c'est comme si on avait écrit char *s; c = (char *) malloc (sizeof(char) * (n + 1)); et c'est ce que fera le compilateur dans le code compilé.
Dans mon code, j'ai fait une erreur. La tabulation est représenté par \9 alors que j'aurais du la représenter par \t. Mais cela n'a pas d'importance à compilation. Lorsque l'on fait un appel à partir d'un batch, script shell ou d'un programme pour lancer un autre programme en lui passant des arguments, dans cette chaîne de caractère, il est nullement interdit de mettre une tabulation. Visuellement, une tabulation est représenté comme une suite d'espace entre deux groupe de caractères. Et, en général, dans le monde de la compilation (personne qui écrive des compilateurs), il est considéré comme un espace. Dans notre cas, il s'agit, donc, d'un séparateur d'argument au même titre que l'espace. Il en existe un autre qui est le retour chariot (je ne rentrerais pas dans le détaille).
Il faudrait le traiter dans ton code.
En relisant ton code, je me suis appercu que tu fais appel à plusieurs boucles. Dans un automate, tu utilises qu'une seule boucle. Je n'ai pas regardé le temps de calcul mais il est claire que si ta donnée à n caractères, ton temps de calcul est supérieure à 2 * n caractères (une fois pour lire le nombre d'argument, une fois pour extraire les arguments). Dans ma méthode, mon temps de calcul est égale à n caractères. Donc en claire, je mets deux fois moins de temps que toi pour réaliser la même chose (a peu près) car je ne délivre pas le nombre d'argument.
En résumer: Dans ma méthode, le compilateur doit coder une boucle et des branchements conditionnels. Dans ta méthode, le compilateur doit coder plusieurs boucles et des branchements conditionnels. Le résultat, c'est que le compilateur en voyant cela va utiliser une pile pour les appels de tes boucles, c'est à dire que il perdera plus de temps empiler et dépiler l'état des boucles qu'à réssoudre le problème.
Maintenant, je dit qu'il faut utiliser un automate et uniquement un automate car il y a des chercheurs en informatique, ayant travaillé sur le sujet, qui ont établi une méthode pour écrire un temps record de tel code. Cela ma pris environs 2min pour mettre sur le papier l'automate et 5min pour l'écrire en C. En moins de 10min, je connaissais, donc, le résultat. Un gain de temps appréciable quand on est en retard dans ces développements et surchargé de travail!
Par contre, je reconnais qu'il faut connaître deux outils mathématique et informatique pour appliquer la méthode:
- les automates de Turing
- les languages fonctionnelles
Ce qui n'est pas donnée à tout le monde. Tout bon livre de sur le sujet de la compilation les abordera car il sont incontournable si il ne l'ai aborde pas, le livre n'est qu'un bouquin permettant d'appliquer sans comprendre tous les mécanismes de mise en oeuvre de la compilation. En général, il traite que d'une seule méthode.
Je vais reviser mon code pour te fournir le nombre d'argument avec la liste des arguments et utiliser une attribution dynamique de la mémoire pour la chaîne de caractères.
cs_bigloo
Messages postés7Date d'inscriptionmercredi 5 octobre 2005StatutMembreDernière intervention 1 novembre 2007 15 oct. 2005 à 15:34
Voici une correction de mon code, il copie la chaîne de caractères tel qu'il injecte des \0 au bonne place et note les adresses de début de chaque sous chaîne dans une structure de liste qui est réinjecté dans un tableau de pointeur de chaine et décompte le nombre de de sous chaîne en une passe.
en entrée:
- ligCommande est la variable de type LPSTR de la fonction WinMain
en sortie:
- nbArg: Nombre d'argument lu dans la ligne de commande
/* Lecture de la ligne de commande mis dans un tableau de chaîne */
char **Arg, *LstArg, c, *str;
int i, nbArg, etat;
etat = 0; // Initialisation de l'état de début de l'automate
i = 0; // Index de scrutation de la chaîne de caractères initialisé à 0
nbArg = 0; // Initialisation du nombre d'argument
// Initialisation de la chaîne de stockage
LstArg = (char *) malloc (sizeof(char) * (strlen(ligCommande) + 1));
LstArg[0] = '\0';
// AUTOMATE
while (etat != 2) { // Négation de la conditon de sortie
// Copie du caractère à l'index i dans la chaîne de stockage
c = ligCommande[i];
LstArg[i] = c;
switch (etat) {
case 0: // Etat initiale
switch (c) {
case ' ': case '\t': break;
case '"': etat = 3; break;
case '\0': etat = 2; break;
default:
aux = (__lstAdr *) malloc (sizeof(char) + 1);
aux->adr = &(LstArg[i]);
aux->next = ptList;
ptList = aux;
etat = 1;
}
break;
case 1: // Reconnaissance d'une chaîne entre espace if ((c ' ') || (c '\t') || (c == '\0')) {
nbArg++;
LstArg[i] = '\0'; if (c '\0') etat 2;
else etat = 0;
}
break;
case 2: break; // Etat Terminal (On ne fait rien, c'est juste pour le marquer
case 3: // Reconnaissance d'une chaîne entre double quote if (c '\0') etat 2;
else {
aux = (__lstAdr *) malloc (sizeof(double) + 1);
aux->adr = &(LstArg[i]);
aux->next = ptList;
ptList = aux;
etat = 5; if (c '"') etat 4;
}
break;
case 4: // Fin de lecture d'une chaîne double quote
etat = 5; if ((c ' ') || (c '\t') || (c == '\0')) {
nbArg++;
LstArg[i-1] = '\0';
etat = 0; if (c '\0') etat 2;
}
break;
case 5: // Chaîne entre double quote avec au moins 1 caractères
switch (c) {
case '"': etat = 4; break;
case '\0': nbArg++; etat = 2; break;
}
break;
}
i++;
}
// Mise en place dans un tableau a deux dymensions des chaînes trouvées
Arg = (char **) malloc (sizeof(char *) * (nbArg + 1));
for (i = nbArg; i > 0; i--) {
Arg[i - 1] = ptList->adr;
aux = ptList;
ptList = ptList->next;
aux->next = NULL
free (aux);
}
Arg[nbArg] = NULL;
cs_bigloo
Messages postés7Date d'inscriptionmercredi 5 octobre 2005StatutMembreDernière intervention 1 novembre 2007 16 oct. 2005 à 00:09
Bonsoir,
Il ne faut pas avoir d'idée préconsu sur la rapidité d'un programme, un programme court n'est pas forcément rapide. Un programme long non plus. Ce n'est pas au nombre de ligne que l'on juge la rapidité d'un programme. Cela se calcul dans certain cas ou se test dans d'autre. Par exemple, si je code cette lecture pour du lua comme c'est de la programmation parallèle, par cas cela va me prendre 1 ligne, soit en 5 lignes, j'ai résolue mon problème de la longueur du programme, géniale!! Et bien non si je code la même chose en listp, cela se code en 1 ligne. J'ai fait mieux ? et bien non. Dans les deux cas, on oubli qu'il y a dérrière un compilateur et un interpréteur qui arrange le coût. Et si on regarde de plus prés le code, on a de forte chance de s'appercevoir qu'ils sont de la même complexité. C'est un mot barbare, mais de nombreux livres en parle.
Comment cela marche:
Dans un premier temps, il faut écrire un algo sur papier reprenant les principales oppérations voulues sur une structure de données et déterminer le nombre de fois que l'on sera obligé de faire une opération élémentaire sur cette structure. La valeur s'exprime en fonction du nombre d'élément dans la structure. En général, on parle en T(x), avec x pouvant prend comme valeur ln(n), en, n, a * n, n2 et nn, ou a est une constante et n le nombre de données dans la structure. Cela est la théorie.
Tu sais bien que l'on peut créer plusieurs structures différentes pour contenir le même type de donnée. Par exemple: pour une liste triée, on peut utiliser un tableau, des arbres binaires, des arbres n-aires et des structures avec indexation par archage. Ce qui est amusant avec cette exemple, c'est en fonction du nombre de données à traiter, il faudra choisir plus une structure qu'une autre. Par chance, il existe plien d'ouvrage sur le sujet qui donne directement la solution:
- moins de 10 éléments, structure tableau avec une ittération simple
- au moins 100 éléments, structure tableau avec une ittération logarithmique
- jusqu'à 2000 élément, structure d'arbre binaire avec une ittération logarithmique
- au delà, structures avec indexation par archage avec une clé oracle
Revenons au problème posé, il s'agit de ligne une chaîne de caractère et d'en extraire les éléments. Bien recherchons les méthodes connues qu'il font déjà cela. Eeuu ... un compilateur. L'une des tâches du compilateur est de lire un fichier source (notre chaîne de caractères), reconnaître les éléments (Typage), vérifier leur ordonnancement (Régle de grammaire pour l'écriture d'un programme), vérifier intégriter des données (Cohérence des types), coder en un language exécutable (Assemblage) et mettre sous forme normale (Régle d'optimisation). Voila ce que fait un compilateur. Le typage est de reconnaître des mots dans le fichier, les ouvrages sur le sujet parle d'automate et termine sur l'utilisation de l'outil LEXX. LEXX est un programme qui prend un ensemble de syntaxe et rend l'automate qui comprend cette ensemble de syntaxe en C, pascal, fortran, etc... (il suffit de lui donner le language cible). Pour notre exemple, on aurait l'ensemble suivant:
- \b\t
- [^"].*[\b\t$]
- ".*"[\b\t$]
Je ne te demande pas de comprend la syntaxe de définition de l'ensemble de syntaxe car il manque la partie exploitation, ou on dit qu'il faut pas prendre en compte les " et \b en début ou en fin, ce n'est pas le but. Les chercheurs ont choisi l'automate pour deux raisons simples:
- d'un état et d'une donnée, il dertermine un nouvel état connu
- il termine toujours (quoi que)
En fait, la deuxième raison n'est pas totalement vrai et est uniquement vrai si on utilise la méthode d'écrit par les chercheurs qui garantie la terminaison de l'automate. On est, donc, capable d'écrire un programme pouvant lire une chaîne de caractères et garantir la terminaison.
Maintenant, un peu d'histoire.
Un type génial a écrit un compilateur qui effectué une lecture du fichier par récurrence. Donc pour écrire son programme, il avais réduit à deux fonctions récursives qui s'appelaient mutuellement. Fort de sa découverte d'un code court permettant de faire de la compilation, il le présente à la communoté des chercheurs en informatique (ce sont plus des mathématicien), et voila, qu'un obcure étudiant japonné en mathématique fondamental mais en défaut son code (Je me souviens plus de son nom mais il a donnée son nom à un algo). Cette première histoire, permet de savoir qu'il faut fuir les fonctions récurssives pour résoudre le problème ce que tu as fait.
Une autre histoire qui est toujours d'actualiter, un suisse avec le concours d'autre personne a écrit un compilateur libre de source pour que ces étudiants puis apprendre la programmation (je parle du language Pascal). La particularité à l'époque de ce compilateur, il compile en une seule passe. C'est à dire qu'il lie une seule fois chaque caractère du fichier source et rend le fichier compilé. Cette second histore, permet de savoir qu'il est possible de lire une unique fois un fichier source pour en extraite les mots du language.
Il reste plus qu'à trouver la bonne structure permettant la lecture en une fois de la chaine de caractères par un automate. Voici l'automate que j'ai mis sur le papier:
eol: représente la fin de la chaîne de caractère
#32: représente la caractère espace
#9: représente le caractère tabulation
@ : action de récupération de l'adresse du caractère lue
+ : action d'incrémentation du nombre d'argument
Maintenant reprenons ton code, tout n'est pas à jeter, l'attribution de mémoire par double pointeur est une excellente idée. Et deux lignes plus bas, façon de parler, tu nous alloue une espace certe suffisant mais bon pourquoi autant de caractères. Cela je peux le comprendre lorsque l'on travail sous UNIX, Linux qui est la taille en standard de la ligne de commande. Si je passe sous Windows, il s'agit de 256. Quoi que, il me semble que l'on peut modifier cette taille et mettre ce que l'on veut du moment qu'il s'agit d'un multi de 128. Imagine, un responsable réseau, pour une obcure raison a décidé d'avoir une autre définition de la taille maximum de la ligne de commande. Ex: il doit taper une commande oracle trés trés longue. Ton code ne marche plus. Mais on garde l'idée du double pointeur et on l'utilise comme un tableau de taille dynamique de pointeur de caractère. Maintenant, tu copie la chaîne de la ligne de commande dans des sous chaînes, l'idée est gardé car cela évite de modifier la ligne de commande en mémoire de la machine (éviter de modifier les données externe) mais sous une autre forme on effectue une copie intelligente. En C, la fin d'un d'une chaîne de caractère est \0, cela tu l'as bien fait, d'où l'idée suivante, on utilise \0 pour effacer les caractères sentinels de la chaîne lue. A chaque fois que l'on ne peut plus effacer, on concerve l'adresse dans le tableau dynamique de pointeur de caractère. A chaque fois que l'on peut a nouveau effacer ou que l'on a attiend la fin de la chaîne, on incrémente le nombre d'argument lue. Comme représenter sur le schémas suivant:
Voici mon code final compilable sous Dev-C++ pour le problème posé:
Avant de le compiler, mettre ces paramétres:
Dans option projet > Paramétres > Compilateur: -Wall
Dans option projet > Paramétres > Editeur de liens: -mWindows
/* Make the class name into a global variable */
char szClassName[ ] = "Win32";
WNDPROC OldEditProc;
/* Définition d'une structure de liste d'argument */
typedef struct __LstArg {
int nbArg;
char **Arg;
char *memoire;
} LstArg;
LRESULT CALLBACK EditProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) {
// Ignorer les touches du clavier si lecture seule: if ((uMsg WM_KEYDOWN) && (wParam VK_DELETE)) return 0;
if ((uMsg == WM_CHAR) && (wParam != VK_RETURN) && (wParam != VK_ESCAPE)) return 0;
// Empêcher selection si bouton gauche appuyé avec déplacement de la souris: if ((uMsg WM_MOUSEMOVE) && (wParam MK_LBUTTON)) return 0;
// Ignorer double clic et EM_SETSEL si non sélectionnable: if ((uMsg WM_LBUTTONDBLCLK) || (uMsg EM_SETSEL)) return 0;
// Ignorer clic droit si Menu contextuel désactivé:
if (uMsg == WM_RBUTTONDOWN) return 0;
// Empecher couper, coller, annuler ou supprimer en lecture seule: if ((uMsg WM_PASTE) || (uMsg WM_CUT) || (uMsg == WM_UNDO) || (uMsg == WM_CLEAR)) return 0;
// Appeler la procédure originale:
return CallWindowProc(OldEditProc, hWnd, uMsg, wParam, lParam);
}
void LectureArgument (LstArg *SArg, LPSTR msg) {
/* Lecture de la ligne de commande mis dans un tableau de chaîne */
char c;
int i, etat;
etat = 0; // Initialisation de l'état de début de l'automate
i = 0; // Index de scrutation de la chaîne de caractères initialisé à 0
/* Initialisation de la variable de retour */
// Initialisation de la chaîne de stockage
SArg->memoire = (char *) malloc (sizeof(char) * (strlen(msg) + 1));
SArg->memoire[0] = '\0';
// Initialisation de la table des arguments
SArg->Arg = (char **) malloc (sizeof(char *) * 1);
SArg->Arg = NULL;
// Initialisation du nombre d'argument lue
SArg->nbArg = 0;
// AUTOMATE
while (etat != 2) { // Négation de la conditon de sortie
// Copie du caractère à l'index i dans la chaîne de stockage
c = msg[i];
SArg->memoire[i] = c;
switch (etat) {
case 0: // Etat initiale
switch (c) {
case ' ': case '\t': break;
case '"': etat = 3; break;
case '\0': etat = 2; break;
default:
SArg->Arg = (char **) realloc (SArg->Arg, sizeof(char *) * (SArg->nbArg + 1));
SArg->Arg[SArg->nbArg] = &(SArg->memoire[i]);
etat = 1;
}
break;
case 1: // Reconnaissance d'une chaîne entre espace if ((c ' ') || (c '\t') || (c == '\0')) {
SArg->nbArg++;
SArg->memoire[i] = '\0'; if (c '\0') etat 2;
else etat = 0;
}
break;
case 2: break; // Etat Terminal (On ne fait rien, c'est juste pour le marquer
case 3: // Reconnaissance d'une chaîne entre double quote if (c '\0') etat 2;
else {
SArg->Arg = (char **) realloc (SArg->Arg, sizeof(char *) * (SArg->nbArg + 1));
SArg->Arg[SArg->nbArg] = &(SArg->memoire[i]);
etat = 5; if (c '"') etat 4;
}
break;
case 4: // Fin de lecture d'une chaîne double quote
etat = 5; if ((c ' ') || (c '\t') || (c == '\0')) {
SArg->nbArg++;
SArg->memoire[i-1] = '\0';
etat = 0; if (c '\0') etat 2;
}
break;
case 5: // Chaîne entre double quote avec au moins 1 caractères
switch (c) {
case '"': etat = 4; break;
case '\0': SArg->nbArg++; etat = 2; break;
}
break;
}
i++;
}
}
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR ligCommande ,
int nFunsterStil)
{
// Déclaration de l'unite de visualisation des informations lues
HWND hEdit;
LstArg *hArg;
int i;
LectureArgument (hArg, ligCommande);
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Lecture des arguments passés à l'exe en Win32", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
430, /* The programs width */
105, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}