Equivalence c/c#

lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006
- 4 août 2005 à 13:52
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006
- 6 août 2005 à 14:27
Salut a tous,

Toujours dans ma recherche de transformation de prog C en C#, je
cherche a verifier la parfaite equivalence entre mon morceau de code C
et celui en C#.

Les resultats que j'obtiens sont quasi les memes mais pas exactement,
ce qui me fais dire que mon prog C# n'est pas encore bon...

Tout aide serait la bienvenue :)

EN C cela donne:


fscanf( infile, "%4c", prefix );

fscanf( infile, "%4c", &nChunkSize );

fscanf( infile, "%8c", fileFormat );

fscanf( infile, "%4c", &nChunkSize );

fscanf( infile, "%2c", &wFormatTag );

fscanf( infile, "%2c", &nChannels );

fscanf( infile, "%4c", &nSamplesPerSecond );

fscanf( infile, "%4c", &nAvgBytesPerSecond );

fscanf( infile, "%2c", &nBlockAlign );

fscanf( infile, "%2c", &nBitsPerSample );

fscanf( infile, "%4s", &ckID );

fscanf( infile, "%4c", &nChunkSize );



for( i = 0; (i < nChunkSize);i++ ) {

fscanf( infile, "%1c", &ch );

byteValue = ((float)ch-128)/128;

fprintf(outfile,"%g\n",byteValue);





L Equivalent(??) en C#

BinaryReader binReader = new BinaryReader(File.Open(fileName, FileMode.Open));

if(binReader.PeekChar() != -1)

{



prefix=binReader.ReadChars(4);



nChunkSize = binReader.ReadUInt32();



fileFormat = binReader.ReadChars(8);



nChunkSize2 = binReader.ReadUInt32();



wFormatTag = binReader.ReadUInt16();



nChannels = binReader.ReadUInt16();



nSamplesPerSecond = binReader.ReadUInt32();



nAvgBytesPerSecond = binReader.ReadUInt32();



nBlockAlign = binReader.ReadInt16();



nBitsPerSample = binReader.ReadInt16();



ckID = binReader.ReadChars(4);



nChunkSize3 = binReader.ReadUInt32();



}

StreamWriter monStreamWriter = new StreamWriter(fileName2);

char ch;

for(int i=0;i<nChunkSize;i++) {

ch=binReader.ReadChar();

byteValue = ((float)ch-128)/128;



monStreamWriter.WriteLine(byteValue);

Console.WriteLine("i:"+i);



}

binReader.Close();

monStreamWriter.Close();



Voila en gros ca lis les header dans mon fichier (Wav) et ca ecrit apres les frquences dans un fichiers RAW.

VOila les valeurs des variables n'est pas les memes entre les 2 programmes, de meme que le fichier RAW de sortie....

A mon avis le probleme viens de mes BinaryReader, avec les Int16-Int32....

Merci

21 réponses

Lutinore
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Membre
Dernière intervention
27 octobre 2012
42
4 août 2005 à 14:32
Salut, as tu pris en compte que les "char" en .NET sont sur 2 octets !?
0
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006

4 août 2005 à 18:02
y a aussi une embrouille avec les Int je sais...
Pourrais tu me conseiller un equivalent?
merci :)
0
SharpMao
Messages postés
1024
Date d'inscription
mardi 4 février 2003
Statut
Membre
Dernière intervention
7 juin 2010
67
5 août 2005 à 08:52
Hello,

Lutinore a raison, les chars en .Net sont sur 2 bytes.

Plutôt que le ReadChars, utilise ReadBytes.

Amicalement, SharpMao
0
Chris_LaFouine
Messages postés
109
Date d'inscription
mardi 13 avril 2004
Statut
Membre
Dernière intervention
4 juin 2008

5 août 2005 à 10:22
Ouais, c'est clair... j'avais bien entamé des classes pour lire les
Tags ID3 v1 et v2 de MP3 et au début, je faisais carrément
ReadString... j'ai compris ma douleur quand je suis tombé sur des
Chr(0)!!!



Ouais, comme le dit SharpMao, utilise ReadBytes... Et après, tu
convertis en dans le format voulu... c'est plus efficace... et
d'ailleurs, c'est que je fais pour virer les octets à 0... parce que ça
merde dès que tu le convertis en String (ou en Char)!!!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006

5 août 2005 à 12:44
Ok j'ai suivi vos conseils, je vous rappel que je suis un debutant total en C# :)

Donc j'ai fais

string prefix;

prefix=(string)binReader.ReadBytes(4);



Il me dis "cannot convert bytes[] to string"

J'ai tenter la meme avec des Char[] prefix=new char[4];

mais il accepte pas le castage que je lui fais :(

Merci en tout cas pour votre aide
0
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006

5 août 2005 à 13:23
bon j'ai tenter ca, il est sur que ca aide :)

par contre je dois vraiment pas le maitriser car pour

fscanf( infile, "%4c", &nChunkSize );
fscanf( infile, "%8c", fileFormat );



j'ai fais :

nChunkSize=Convert.ToUInt32(binReader.ReadBytes(4));

for(int i=0;i<8;i++) { fileFormat[i]=Convert.ToChar(binReader.ReadByte()); }



mais j'ai une erreur lors de lexcution du programme notemment a cause du Convert.ToUint32...

Ma question un %4c tiens sur un Int16?Int32? de meme pour %2c

Quand je fais nChunkSize=Convert.ToUInt16(binReader.ReadBytes(4)); alors nchunksize=0...

bref je m en sort pas :(

merci
0
Chris_LaFouine
Messages postés
109
Date d'inscription
mardi 13 avril 2004
Statut
Membre
Dernière intervention
4 juin 2008

5 août 2005 à 13:51
Pour le premier problème, essayes ça :

String prefix = binReader.ReadBytes(4).ToString();



Pour le deuxième problème :

Int16-->16 bits donc 2 octets

Int32-->32 bits donc 4 octets

%4c-->4 octets car 1c fait 1octet...



Je crois que tu as ta réponse...



Par contre, pour ce qui est du :

nChunkSize=Convert.ToUInt32(binReader.ReadBytes(4));

C'est normal que ça fonctionne pas. Si tu regardes les prototypes de
Convert.ToUInt32, tu verras qu'il y a en pas qui prennent en compte un
tableau de Bytes. Si je comprends bien, ce que tu veux faire c'est que
si ton binReader.ReadBytes(4) contient :

1 (01 en hexa)

30 (1E en hexa)

68 (44 en hexa)

7 (07 en hexa)

tu veux mettre la valeur numérique de 011E4407 (hexa) dans ta variable Int32 ce qui fait : 18760711 (en décimal).



Dis moi si je me trompe!

Si je suis sur la bonne voie, je crois que tu as gagné le droit de te faire ta propre fonction!
0
SharpMao
Messages postés
1024
Date d'inscription
mardi 4 février 2003
Statut
Membre
Dernière intervention
7 juin 2010
67
5 août 2005 à 14:14
Hello,

Pour les entiers, tu peux continuer à faire comme avant (ReadUIntXX).
Pour les String, essaie avec

System.Text.Encoding.Ascii.GetString(binReader.ReadBytes(4));
ou avec
System.Text.Encoding.UTF8.GetString(binReader.ReadBytes(4));

Amicalement, SharpMao
0
Lutinore
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Membre
Dernière intervention
27 octobre 2012
42
5 août 2005 à 14:41
Le constructeur de la classe BinaryReader accepte un paramètre "encoding", par défaut c'est sûrement du UTF8, comme SharpMao je pense qu'avec un encodeur ASCII ca devrait lire les chars sur un octet.
0
SharpMao
Messages postés
1024
Date d'inscription
mardi 4 février 2003
Statut
Membre
Dernière intervention
7 juin 2010
67
5 août 2005 à 15:08
Par défaut, c'est Encoding.Default, sauf erreur, et il y a de forte chance que ce soit un Encoding avec 16 bits/char

Amicalement, SharpMao
0
Lutinore
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Membre
Dernière intervention
27 octobre 2012
42
5 août 2005 à 15:19
UTF8 par défaut pour le BinaryReader.
0
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006

5 août 2005 à 15:19
bon deja merci a tous pour vos reponses :)

J'explique j'essai de lire le header d'un fichier WAV afin de le tranformer en fichier RAW.

Pour ce faire j'ai repris un code source (en C) libre de droits,
et je m'en inspire pour faire mon petit programme a moi en C#.

Pour le prefix j'ai reussi a resoudre en utilisant effectivement le toString.

Par contre Chris, je ne sais pas du tout le resultat que je veux avoir, dans mes int.

1 (01 en hexa)
30 (1E en hexa)
68 (44 en hexa)
7 (07 en hexa)
tu veux mettre la valeur numérique de 011E4407 (hexa) dans ta variable Int32 ce qui fait : 18760711 (en décimal).

Aucun idee si cela correspond concretement a ce que je veux.

Je sais simplement que je veux transformer

fscanf( infile, "%4c", &nChunkSize ); en C#.

Ce qui signifie recuperer les 4 bytes et les mettres dans un Int. Chose
qui parait simple en C mais pas en C# lol Donc normalement comme c'est
4c->Int32



Bon par contre en ce qui concerne UTF8 ( enclair les 3 derniers msg 0 j'ai aps trop compris lol

MERCI A TOUS je vais continuer et essayer de voir :)

je vous tiens au courant
0
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006

5 août 2005 à 15:28
pardon ej reviens juste sur un petit truc :)

Qu'est ce qui me fais dire que mes resultats ne sont pas bon :)

En utilisant mon programme c#

if(binReader.PeekChar() != -1)

{


for(int
i=0;i<4;i++) { prefix[i]=Convert.ToChar(binReader.ReadByte()); }



nChunkSize=binReader.ReadUInt32();


for(int
i=0;i<8;i++) { fileFormat[i]=Convert.ToChar(binReader.ReadByte()); }



nChunkSize2 = binReader.ReadUInt32();



wFormatTag = binReader.ReadUInt16();



nChannels = binReader.ReadUInt16();



nSamplesPerSecond = binReader.ReadUInt32();



nAvgBytesPerSecond = binReader.ReadUInt32();



nBlockAlign = binReader.ReadInt16();



nBitsPerSample = binReader.ReadInt16();


for(int
i=0;i<4;i++) { ckID[i]=Convert.ToChar(binReader.ReadByte()); }



nChunkSize3 = binReader.ReadUInt32();



}



StreamWriter monStreamWriter = new StreamWriter(fileName2);

char ch;

for(int i=0;i<nChunkSize3;i++) {



ch=binReader.ReadChar(); =========>bug

byteValue = ((float)ch-128)/128;



monStreamWriter.WriteLine(byteValue);

//Console.WriteLine("i:"+i);



}



Bah en fait ca bug, en fait cela proviens de la boucle, ou je depasse la limite du fichier.

Ce qui pour moi signifie que nChunkSize3 n'a pas la taille qu'il faut, il est trop grand....

J'en viens donc a l'evidence que les nombres entres dans les entetes ne sont pas bon :)

Voila merci
0
Chris_LaFouine
Messages postés
109
Date d'inscription
mardi 13 avril 2004
Statut
Membre
Dernière intervention
4 juin 2008

5 août 2005 à 15:40
Fait un "monStreamWriter.Flush()" pour forcer l'écriture.



Sinon, en ce qui concerne le probleme Int32 et %4c, y a un truc que je comprends pas...

Pourquoi tu veux mettre 4 Bytes dans 1 Int32... c'est pas logique. T'as déjà essayé de faire loger 4 personnes dans 1 chiotte? C'est pas normal! (Désolé pour l'exemple, mais c'est le premier qui me vient à l'esprit ).



Si tu veux récupérer 4 Bytes pour les mettre dans un tableau de 4 Int16 (ou 32), c'est pas compliqué :

Int16[] tabInt = (Int16)monBinaryReader.GetBytes(4);



Mais si tu veux que la suite des 4 Bytes que tu as récupéré en lisant dans le fichier soit interprété comme 1 Int32, c'est un peu plus tendu et c'est là où tu devras faire une fonction!
0
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006

5 août 2005 à 15:45
alors le flush je le fais quand? juste apres avoir creer le SteamWriter?



Sinon en fait ca devrai etre je recupere les 4 bytes qui sront interpreter comme un Int32...

C'est ce que j'ai compris de mes lecture sur les entetes des fichiers
WAV, et c'est que dis le programme en C que j'ai donner a l'origine du
post fscanf( infile, "%4c", &nChunkSize ); je veux reellement transformer cela en C# donc a priori 4 bites dans un Int....

Donc a priori ca doit etre ca...

Je pense donc avoir a faire une fonction pour cela...

thx
0
Chris_LaFouine
Messages postés
109
Date d'inscription
mardi 13 avril 2004
Statut
Membre
Dernière intervention
4 juin 2008

5 août 2005 à 15:58
Tu peux me mettre la déclaration de ton "nChunkSize" en C, s'il te plait?



Sinon, pour le Flush, fait le tout les Mo à la limite. Dans ton for, tu vas faire un truc de ce style :



for(i=0; i=.....) {

if( i % 1000000 == 0 ) {

monBinaryWriter.Flush();

}

monBinaryWriter.Write(byteValue);

}



Par contre, y a peut-être mieux niveau optimisation!
0
SharpMao
Messages postés
1024
Date d'inscription
mardi 4 février 2003
Statut
Membre
Dernière intervention
7 juin 2010
67
5 août 2005 à 16:19
Chris_LaFouine, un Int32 est composé de 4 bytes, ça se justifie donc totalement.

Amicalement, SharpMao
0
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006

5 août 2005 à 16:34
merci

Voici la declaration des variables en C



char prefix[4];

char fileFormat[8];

unsigned char ch;

float byteValue;

unsigned int i;

char ckID[4];

unsigned long nChunkSize;

short int wFormatTag;

short int nChannels;

unsigned long nSamplesPerSecond;

unsigned long nAvgBytesPerSecond;

short int nBlockAlign;

short int nBitsPerSample;



fscanf( infile, "%4c", prefix );
fscanf( infile, "%4c", &nChunkSize );
fscanf( infile, "%8c", fileFormat );
fscanf( infile, "%4c", &nChunkSize );
fscanf( infile, "%2c", &wFormatTag );
fscanf( infile, "%2c", &nChannels );
fscanf( infile, "%4c", &nSamplesPerSecond );
fscanf( infile, "%4c", &nAvgBytesPerSecond );
fscanf( infile, "%2c", &nBlockAlign );
fscanf( infile, "%2c", &nBitsPerSample );
fscanf( infile, "%4s", &ckID );
fscanf( infile, "%4c", &nChunkSize );
0
Chris_LaFouine
Messages postés
109
Date d'inscription
mardi 13 avril 2004
Statut
Membre
Dernière intervention
4 juin 2008

5 août 2005 à 17:05
Okay, donc ce que tu veux faire c'est vraiment ce que je disais avec mes exemples en Hexadécimal!



J'ai une solution à ce problème, mais c'est en VB.NET, faut que je le
traduise! Et puis, c'est pas du tout optimisé. mais en gros l'idée
générale :



public static Int32 bytesToInt(Byte[] tab)

{

String res="";

for(i=0;i<tab.Lenght;i++){

res += decToBin(tab[i]);

}

return binToDec(res);

}



//Renvoie un String ayant la valeur en binaire de b

//Exemple : decToBin(64) renvoie "0100000"

public static String decToBin(Byte b);



//Renvoie un Int32 correspondant à la valeur binaire de la chaine passée en paramètre

//Exemple : binToDec("10000000") renvoie 128

public static Int32 binToDec(String str);
0
lezabour55
Messages postés
22
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
18 juillet 2006

5 août 2005 à 19:21
ok je commence a comprendre mon erreur!

je ne pense pas maitriser assez les conversion Binaire/Decimal pour pouvoir l'ecrire en programme!

Voila ce que j'ai trouver/modifier/fait pour le moment :)

public int GetBinaryValue(int valeur) {

int lValue = 0;

int division = valeur;

for (int i=0 ; division > 0; i++) {

if (division % 2 == 1)

lValue += (int)Math.Pow(10,i);

division = division /2;

}

return lValue;

}



public Int32 BinaireToDec(String str) {

string Car="";

int CarInt=0,ValeurDec=0;

for (int i=1;i<=str.Length;i++) {

/*On fait la conversion de base 2 en base 10*/



Car=str.Substring(str.Length-i,1);

CarInt=Convert.ToInt16(Car);

ValeurDec=ValeurDec+(int)(CarInt*Math.Pow(2,i-1));

}

return ValeurDec;

}



public Int32 bytesToInt(Byte[] tab) {

string res="";

for(int i=0;i<tab.Length;i++) {

res += GetBinaryValue(tab[i]);

}

return BinaireToDec(res);

}



Bon ca approche mais c'est toujours pas bon :) J'ai donc modifier le
code qui donne a chaque variable sa valeur pour que cela donne:



prefix=binReader.ReadBytes(4).ToString();//binReader.ReadChars(4);



nChunkSize=bytesToInt(binReader.ReadBytes(4));


for(int
i=0;i<8;i++) { fileFormat[i]=Convert.ToChar(binReader.ReadByte()); }



nChunkSize2 = bytesToInt(binReader.ReadBytes(4));



wFormatTag = binReader.ReadUInt16();



nChannels = binReader.ReadUInt16();



nSamplesPerSecond = bytesToInt(binReader.ReadBytes(4));



nAvgBytesPerSecond = bytesToInt(binReader.ReadBytes(4));



nBlockAlign = binReader.ReadInt16();



nBitsPerSample = binReader.ReadInt16();


for(int
i=0;i<4;i++) { ckID[i]=Convert.ToChar(binReader.ReadByte()); }



nChunkSize3 = bytesToInt(binReader.ReadBytes(4));

Bon je fais plusieurs test, evidemment ce code n'a rien de definitif :)

Mais ca ne marche toujours pas, le probleme viens la a mon avis de mes fonctions Binaire et Decimal...



Autre petit indice nChunkSize3 313260 grace a nChunkSize3 bytesToInt(binReader.ReadBytes(4));

Alors que ma boucle bloque lorsque i=222413...

Je devrai avoir, quand la boucle a fini i=nChunkSize3...

MErci beaucoup a tous :)
0