CHANGER LA DATE DE CRÉATION/MODIFICATION DE FICHIERS AVEC UN ÉQUIVALENT DU "TOUC

Nicky22 Messages postés 4 Date d'inscription vendredi 14 juillet 2006 Statut Membre Dernière intervention 19 janvier 2009 - 16 janv. 2009 à 04:47
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 19 janv. 2009 à 11:53
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/48987-changer-la-date-de-creation-modification-de-fichiers-avec-un-equivalent-du-touch-unix-ms-dos

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
19 janv. 2009 à 11:53
Salut,
Il n'y a que le vieux VS6 pour linker avec MFC42, toute version ultérieure doit fournir un setup ou livrer un exe monumental.

TESTONS:
#define _WIN32_WINNT 0x0600
#define _WIN32_IE 0x0700
#include <windows.h>

char szappname[] = "chrTst";

void fncTst(VOID)
{
char buf[40] = {0};
buf[0] = 'a';
MessageBox(0, buf, szappname, 0);
}

#pragma comment(linker, "/entry:myWinMain")
__declspec(naked) void __stdcall myWinMain()
{
__asm {
call fncTst
call fncTst
push 0
call dword ptr ExitProcess
}
}

LISTING ASM DU COMPILO:
_buf$ = -40
_fncTst@0 PROC
sub esp, 40
; 10 : char buf[40] = {0};
push 39
lea eax, DWORD PTR _buf$[esp+45]
push 0
push eax
call _memset
add esp, 12
; 11 : buf[0] = 'a';
; 12 : MessageBox(0, buf, szappname, 0);
push 0
push OFFSET _szappname
lea ecx, DWORD PTR _buf$[esp+48]
push ecx
push 0
mov BYTE PTR _buf$[esp+56], 97
call DWORD PTR __imp__MessageBoxA@16
add esp, 40
ret 0
_fncTst@0 ENDP

EXE fait 5 Ko et appel memset() sans équivoque.

Avec:
void fncTst(VOID)
{
char buf[40];
buf[0] = 'a';
buf[1] = 0;
MessageBox(0, buf, szappname, 0);
}

ON OBTIENT:
_buf$ = -40
_fncTst@0 PROC
sub esp, 40
; 9 : char buf[40];
; 10 : buf[0] = 'a';
; 11 : buf[1] = 0;
; 12 : MessageBox(0, buf, szappname, 0);
push 0
push OFFSET _szappname
lea eax, DWORD PTR _buf$[esp+48]
push eax
push 0
mov BYTE PTR _buf$[esp+56], 97
mov BYTE PTR _buf$[esp+57], 0
call DWORD PTR __imp__MessageBoxA@16
add esp, 40
ret 0
_fncTst@0 ENDP

EXE = 2.5 Ko et code optimal, y a pas photo.
Nicky22 Messages postés 4 Date d'inscription vendredi 14 juillet 2006 Statut Membre Dernière intervention 19 janvier 2009
19 janv. 2009 à 05:19
Re-salut BruNews, je n'avais pas vu votre pedigree... bravo !
Vous avez donc certainement de meilleures connaissances que moi en assembleur...
Du coup, j'ai eu un doute sur le nombre d'évaluations de strlen dans la boucle if.
Un petit bout de code de test m'a montré que vous aviez 100% raison.
Il vaut donc mieux remplacer mon code initial
for (i=0;i<strlen(sz);i++) { ... }
par
int n=strlen(sz);
for (i=0;i<n;i++) { ... }
A+
Nicky22 Messages postés 4 Date d'inscription vendredi 14 juillet 2006 Statut Membre Dernière intervention 19 janvier 2009
19 janv. 2009 à 03:26
Merci BruNews de votre commentaire.

Il est toujours possible de coder de multiples manières... et en fonction du but recherché (intérêt pédagogique, efficacité, robustesse, rapidité d'écriture, lisibilité, portabilité, ré-utilisabilité, etc.), certains choix sont meilleurs que d'autres.

Mais vous énoncez quelques vérités qui ... ne le sont pas :

- écrire char XX[xx]={0} n'équivaut pas à un memset, mais force juste le 1er caractère de la chaine à zéro. En debug, la chaine est de toute façon toute mise à zéro, mais pas en release. J'ai pris cette bonne habitude d'initialiser systématiquement chaque variable il y a longtemps...et ne m'en suis jamais plaint (sauf dans certains cas d'optimisation).
- le strlen dans le test de la boucle "if" ne sera évalué qu'une seule fois.
- Un setup pour déployer les MFC est inutile si on compile le projet en release, mfc42.dll se trouve dans Windows depuis 95/98 (et pas mfc42d.dll, si compilé debug, je vous l'accorde). Enfin, si ça vous inquiète toujours, vous pouvez toujours faire un "static link" avec les .lib des MFC...

Enfin, dans le rayon goûts et couleurs,
- j'aime pas les goto en C, mais à chacun ses marottes !
- OK pour la "surcouche" des MFC, on perd sans doute un peu de perfos (mais sont-elles vraiment requises dans un programme de ce genre ?). Avantages : facilité d'écriture, robustesse et lisibilité (qualités primordiales dans l'industrie). Inconvénient majeur : portabilité.

Pour illustrer ce dernier propos, seriez-vous prêt à réécrire la fonction CString::Replace() juste pour optimiser le code ? D'un point de vue pédagogique, c'est assez intéressant, mais bon...

En tous cas, merci de m'avoir donné l'occasion de débattre avec vous.
Intéressant !
Amicalement / NC
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 janv. 2009 à 14:54
Voyons cette fonction:
LPCTSTR stristr(LPCTSTR string, LPCTSTR strCharSet)
{
char *pStr=NULL;
char szUpBuffer[1024]={0};
char szUpCharSet[127]={0};
UINT i;
for(i 0; i < strlen(string) + 1; i++) szUpBuffer[i] (char)toupper(string[i]);
for(i 0; i < strlen(strCharSet) + 1; i++) szUpCharSet[i] (char)toupper(strCharSet[i]);
pStr = strstr(szUpBuffer, szUpCharSet);
if(!pStr) return NULL;
i = pStr - szUpBuffer;
pStr = (char*) string+i;
return pStr;
}

char szUpBuffer[1024]={0};
A quoi sert de forcer un memset() sur des buffers locaux ? à rien puisqu'on va y recopier des chaine qui ont donc un zero teminateur.

for(i 0; i < strlen(string) + 1; i++) szUpBuffer[i] (char)toupper(string[i]);
Recalcul strlen() à chaque tour ???
On remplacera par:
char *c, *d;
c = string;
d = szUpBuffer;
while(*c) *d++ = (char) toupper(*c++);
*d = 0;

On obtient donc:
LPCTSTR stristr(LPCTSTR string, LPCTSTR strCharSet)
{
char szUpBuffer[1024], szUpCharSet[127], *c, *d;
c = string;
d = szUpBuffer;
while(*c) *d++ = (char) toupper(*c++);
*d = 0;
c = strCharSet;
d = szUpCharSet;
while(*c) *d++ = (char) toupper(*c++);
*d = 0;
c = strstr(szUpBuffer, szUpCharSet);
if(!c) goto strEXIT;
c = string + (c - szUpBuffer);
strEXIT: return c;
}

Tout l'ensemble du code est à revoir sur ce modèle.

Autre sujet:
Pourquoi employer MFC (ou autre surcouche) pour un mini utilitaire de ce genre ?
Pour cause de MFC, il faut par force un setup pour le distribuer.
Il suffit de remplacer les CString et autres Ctrucmuche par un peu de code pour rendre l'exe indépendant.
gillardg Messages postés 3275 Date d'inscription jeudi 3 avril 2008 Statut Membre Dernière intervention 14 septembre 2014 2
17 janv. 2009 à 12:21
Nicky22 Messages postés 4 Date d'inscription vendredi 14 juillet 2006 Statut Membre Dernière intervention 19 janvier 2009
16 janv. 2009 à 04:47
Petit bug expliquant le non-fonctionnement, comme vu sur la capture :
il fallait bien évidemment coder :
if (nDay < 1 || nDay >31) return CTime(0);
et non pas :
if (nDay <= 1 || nDay >31) return CTime(0);
Rejoignez-nous