Probleme de param

Résolu
Signaler
Messages postés
24
Date d'inscription
samedi 28 décembre 2002
Statut
Membre
Dernière intervention
1 février 2005
-
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
-
Je vien tout juste de créer un tit prog pour convertir un fichier en fichier texte
hexadecimal. Je suis quelque peu débutant en c/c++ alors je voudrais savoir
comment je pourrais améliorer celui-ci. J'ai aussi un petit probleme:

la façon dont ce prog fonctionne c'est que je glisse un fichier dessu et il le
convertit, mais lorsque j'en glisse plusieurs à la fois, il ne les convertit pas tous:
si je glisse 2 fichier, il en converti 1;
3 -> 2;
4 -> 2;
5 -> 3;

j'ai essayer de plusieurs façon et c'est toujours le même probleme, même
en passant les parametre a l'aide de l'invite de command windows.

Merci d'avance!

The Universal ßð¥

10 réponses

Messages postés
224
Date d'inscription
mardi 12 août 2003
Statut
Membre
Dernière intervention
18 octobre 2010

char *SrcFile, *DestFile;
//...
DestFile=strcat(SrcFile,".txt");

oula ca marche ça chez toi? Je pense que ça ecrase les valeurs suivantes de argv
essaye plutot ca

char *SrcFile,DestFile[MAX_PATH]
//...
strcpy(DestFile,SrcFile);
strcat(DestFile,".txt");
Messages postés
24
Date d'inscription
samedi 28 décembre 2002
Statut
Membre
Dernière intervention
1 février 2005

J'ai oublier de mettre la source:

#include <windows.h>
#include <math.h>


char* ByteToHex(BYTE c)
{
const char H[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
float n;
int i;
char h[2];
char *r;
n=c;
n=n/16;
i=(int)floor(n);
h[0]=H[i];
n=n-i;
n=n*16;
i=(int)n;
h[1]=H[i];
r=h;
return r;
}


int main(int argc,char **argv)
{
HANDLE hSrcFile, hDestFile;
char *SrcFile, *DestFile;


for(int i=1;i!=argc;i++)
{
SrcFile=argv[i];


hSrcFile = CreateFile(SrcFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);


if(hSrcFile != INVALID_HANDLE_VALUE)
{
DestFile=strcat(SrcFile,".txt");


hDestFile = CreateFile(DestFile,
GENERIC_WRITE,
NULL,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);


if(hSrcFile != INVALID_HANDLE_VALUE)
{
char SrcData[1024], DestData[2048];
int FileSize = GetFileSize(hSrcFile,NULL)-1;
DWORD nobr, nobw;
char *Hex;
bool eof=false;


while(!eof)
{
ReadFile(hSrcFile, SrcData, 1024, &nobr, 0);

for(int n=0;n<(int)nobr;n++)
{
Hex=ByteToHex(SrcData[n]);
DestData[n*2]=Hex[0];
DestData[n*2+1]=Hex[1];
}


WriteFile(hDestFile, DestData, nobr*2, &nobw,0);

if(nobr!=1024) eof=true;
}
}


CloseHandle(hDestFile);
}


CloseHandle(hSrcFile);
}
return 0;
}

The Universal ßð¥
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
Faut refaire ta ByteToHex(), une calamité en terme de performance. Supprime le float et ne bosser que sur du UINT.

ciao...
BruNews, MVP VC++
Messages postés
24
Date d'inscription
samedi 28 décembre 2002
Statut
Membre
Dernière intervention
1 février 2005

Salut BruNews,

J'ai chercher un peu sur le site pour des fonctions de conversion vers hexa, mais je n'en ai trouvé aucune utilisant UINT, mais j'ai vu ta fonction IntToBin qui est très intéressante!

Je voudrais savoir, comment tu ferais un ByteToHex ou IntToHex ou CharToHex (laquelle de ces fonctions serait la meilleure) ?

Merci

The Universal ßð¥
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Non seulement elle n'est pas optimisée mais en plus erronée. On ne renvoi JAMAIS un pointeur sur une variable ou buffer local à une fonction. Pour renvoyer un pointeur il faut soit l'allouer soit utiliser une variable static. Dans ton cas ça marche peut-être car la pile n'est pas utilisée après l'appel de la fonction mais en général ça plante.

le plus simple :
szVal[3];
BYTE b = 123;
BYTE hi = (b>>4)&0xf;
BYTE lo = b&0xf;
szVal[0] = (hi<=9) ? '0'+hi : 'A'+hi-10;
szVal[1] = (lo<=9) ? '0'+lo : 'A'+lo-10;
szVal[2] = '\0';

sinon il y a la fonction atoi qui permet de transformer un entier en chaîne dans la base que tu veux (16 pour toi)
szVal[16];
BYTE b = 123;
itoa(b, szVal, 16);
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
ah oui, retour d'un pointeur sur variable locale, je n'avais pas lu jusqu'au bout.

ciao...
BruNews, MVP VC++
Messages postés
24
Date d'inscription
samedi 28 décembre 2002
Statut
Membre
Dernière intervention
1 février 2005

Salut ymca,

en me basant sur la function IntToBin de BruNews et ta suggestion, j'ai écrit ceci:

char* __stdcall StrToHex(char *str, char *psz)
{
for(int i=0;i<5000;i++)
{
int hi = (str[i]>>4)&0xf;
int lo = str[i]&0xf;

*psz++ = (hi<=9) ? 48+hi : 55+hi;
*psz++ = (lo<=9) ? 48+lo : 55+lo;
}
*psz = 0;
return psz;
}

puis j'ai tester ceci
*psz++ = 48+hi+7*(hi>=9);
*psz++ = 48+lo+7*(lo>=9);
au lieu de ceci
*psz++ = (hi<=9) ? 48+hi : 55+hi;
*psz++ = (lo<=9) ? 48+lo : 55+lo;

puis j'ai fais les test de vitesse, et ma fonction est plus rapide que celle que tu ma suggéré...
J'ai aussi testé avec itoa, mais c'est beaucoup trop lent!!!

SOURCE DU TEST DE VITESSE:

#include <windows.h>
#include <stdio.h>
#include <time.h>


char* __stdcall StrToHex(char *str, char *psz)
{
for(int i=0;i<5000;i++)
{
int hi = (str[i]>>4)&0xf;
int lo = str[i]&0xf;

//ma facon:
*psz++ = 48+hi+7*(hi>=9);
*psz++ = 48+lo+7*(lo>=9);
//ta façon:
//*psz++ = (hi<=9) ? 48+hi : 55+hi;
//*psz++ = (lo<=9) ? 48+lo : 55+lo;
}

*psz = 0;
return psz;
}


int main() {
char tmp [10000],mstr [5000];
clock_t t1,t2;
srand(time(NULL));
for(int i=0; i<5000; i++)
{
mstr[i]=rand()%255;
}


t1=clock();
for (i=0 ; i < 10000; i++ ) {
StrToHex(mstr,tmp);
}
printf(tmp);
t2=clock();
printf("Temps d'execution: %d ms\n",(t2-t1));
return 0;
}

Merci quand même pour ta suggestion sans laquelle je n'aurais jamais pu faire la mienne :)

The Universal ßð¥
Messages postés
24
Date d'inscription
samedi 28 décembre 2002
Statut
Membre
Dernière intervention
1 février 2005

Petite question en passant:

j'ai mit for(int i=0; i<5000;i++) en sachant que "str" aurait tjrs 5000 caratere ds mon teste mais comment faire pour detecter la vrai longeur du buffer str??

strlen ? sizeof ? ou quoi?

J'en profite aussi pour remercier BruNews....

The Universal ßð¥
Messages postés
24
Date d'inscription
samedi 28 décembre 2002
Statut
Membre
Dernière intervention
1 février 2005

Correction:

*psz++ = 48+hi+7*(hi>=9);
*psz++ = 48+lo+7*(lo>=9);

hi>=9 doit etre hi>=10 ou hi>9
lo>=9 doit etre lo>=10 ou lo>9

resultat:

*psz++ = 48+hi+7*(hi>9);
*psz++ = 48+lo+7*(lo>9);

The Universal ßð¥
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Ue chaîne de caractère en C se termine toujours par un caractère nul (0 ou '\0') il suffit donc de tester cette valeur pour sortir de la boucle. On peut également utiliser strlen pour connaître la taille mais dans ton cas cela reviendrait à parcourir 2 fois la chaîne (une fois pour connaître sa taille et une autre pour faire la conversion).

PS : on n'utilise pas sizeof sur une chaîne de caractères passée en paramètre par l'intermédiare d'un pointeur car cela renverra toujours 4 (sur plateforme 32 bits).