(MFC) Convertir un CString en char[ ]/char * [Résolu]

Signaler
Messages postés
7
Date d'inscription
lundi 14 mars 2005
Statut
Membre
Dernière intervention
10 avril 2005
-
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
-
Bonjour tout le monde



Bon voilà, je débute en C++ et encore plus avec les MFC et je galère un peu..

alors après avoir passé plusieurs heures aujourd'hui et hier


a chercher sur le net ou dans la msdn comment convertir un CString en char *je me résigne à venir demander sur le forum!!!


A mon avis,on vous a déjà demandé mais j'ai pas trouvé...



J'explique mon pb:


Je programme un client/serveur de transfert de fichier avec des MFC.Je dois donc récupérer le nom de fichier de type CString.


et l'envoyer à travers la socket mais celle-ci n'accpete pas les
CString, juste les char * (et meme pas const char)....et je n'arrive
pas a le convertir.


De l'autre coté je devrai reconvertir le char * en CString.




J'ai essayé un peu tout ce qui était donné sur les forums à savoir

par exemple : char* NameFile = (char*)LPCTSTR(NomFichier);

ou WideCharToMultiByte mais sa me fait des erreurs suivante:

1)


C:\Projet Informatique\IHM\PCEtude\CTransfert.cpp(55) : error
C2664: 'wcslen' : cannot convert parameter 1 from 'class CString' to
'const unsigned short *'


No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called




2)C:\Projet Informatique\IHM\PCEtude\CTransfert.cpp(55) :
error C2664: 'WideCharToMultiByte' : cannot convert parameter 3 from
'class CString' to 'const unsigned short *'


No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called




Sinon mon code est celui ci


<li>//Methode d'envoie de donnée
</li><li>int CTransfert::EnvoyerDonnee(CString Chemin, CString NomFichier)
</li><li>{
</li><li> char *NomFichierStr;
</li><li> WideCharToMultiByte(CP_ACP, 0, NomFichier, -1, NomFichierStr, wcslen(NomFichier)+1, NULL, NULL);
</li><li> //Prend en parametre le chemin du fichier et son Nom;
</li><li> send(Client.sock, NomFichierStr, sizeof(NomFichierStr),0);
</li><li> /*Ouverture du fichier en Lecture et en mode Binaire*/
</li><li> fileFlux.open(Chemin, ios::in | ios::binary);
</li><li> if (fileFlux.fail())
</li><li> return(-1);
</li><li> //Si l'ouverture echoue, on quitte et on renvoie -1
</li><li> else
</li><li> { //Tant qu'on est pas a la fin du fichier, on lit..
</li><li> while ((fileFlux.read(&charLuEnvoye, 1)) != 0)
</li><li> /*..et chaque caractere lu est envoyer par la socket
</li><li> du client (declarer dans Transfert.h)*/
</li><li> send(Client.sock, &charLuEnvoye, 1, 0);
</li><li> fileFlux.close();
</li><li> return (0);
</li><li> //on retourne 0 lorsque tout est terminé ou si il n'y a pas d'erreur
</li><li> }
</li><li> /*Fermeture du fichier*/
</li><li>}</li>



voilà , si vous pouviez m'aider se serai vraiment cool car la sa fait
depuis hier aprem quasi non stop que je suis dessu et je galere...j'ai
demandé sur un autre forum mais ce qu'on ma conseiller j'ai pas trop
trop comprit...

"
CString -> LPTSTR (just un define de char*) : GetBuffer


char* -> CString : avec le constructeur..."



Merci d'avances...

9 réponses

Messages postés
7
Date d'inscription
lundi 14 mars 2005
Statut
Membre
Dernière intervention
10 avril 2005

bon et bien je crois que j'ai reussi a trouver et a faire en sorte que sa marche correctement...c'est un peut porc mais bon



niveau client sa fait sa (j'ai supprimer le itoa etc...et jai directement mit 200 dans send)

// i = NomFichier.GetLength();

// itoa(i,taille,25);

// send(Client.sock, taille, sizeof(taille) , 0);



send(Client.sock, (LPTSTR)(LPCTSTR)NomFichier, 200 ,0);



niveau serveur sa fait , pareil je met 200....

je n'ai plus de debordement, le fichier se transmet correcte et le nom du fichier n'est pas transformé...



recv(Serveur.sockTransfert, (LPTSTR)(LPCTSTR)NameFileCString, 200,0);





Voilà , en tout cas merci beaucoup pour votre aide car sinon je galererai encore a cette heure ci!!!!
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
send(Client.sock, NomFichierStr, sizeof(NomFichierStr),0);
=>
send(Client.sock, NomFichierStr, strlen(NomFichierStr),0);

sinon
send(Client.sock, (LPTSTR)(LPCTSTR)NomFichier, NomFichier.GetLength(),0); devrait marcher sauf si tu compile en UNICODE auquel cas il faut effectivement faire la conversion WideCharToMultiByte. Par contre il faut être sur que send ne modifie PAS la chaîne passée.
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Autre truc lit le fichier et envoie le par bloc (de qqs Ko par exemples)
Messages postés
7
Date d'inscription
lundi 14 mars 2005
Statut
Membre
Dernière intervention
10 avril 2005

Oui en faite j'envoie 1 octet par 1 octet car le fichier que je dois
envoyer est un fichier dxf (contenant que du texte) et en general la
taille du fichier n'excede pas 10Ko...donc pour si peu je me suis dit
que j'enverrai octect par octet.

Mais quand je le reprendrai et que je le ferai evolué pour de gros fichier, j'enverrai des bloc de 1024 ou 2048 octets...:)

En tout cas merci d'avoir répondu!!! je vais aller essayer tout sa ...



Ps : une fois que j'aurais tout fini mon proj , je le mettrai a dispo sur le site!
Messages postés
7
Date d'inscription
lundi 14 mars 2005
Statut
Membre
Dernière intervention
10 avril 2005

Alors en effet cela marche comme ça!!

Il n'y a plus de pb de constant char ou char * etc...

(peut on m'expliker pourquoi car j'aimerai savoir...lol)



Par contre de l'autre coté, sa marche ausis mais sa receptionne mal ,
surement a cause de la taille que je met....je sais pas qu'elle taille
je dois mettre...si je met un NameFileCString.GetLength(), sa ne marche
pas car la taille vaut alors 0...et si je met plus sa prend des
caractere du ficher et le met en nom de fichier ....

voila le code:

int CTransfert::RecevoirDonnee(void)

{

recv(Serveur.sockTransfert, (LPTSTR)(LPCTSTR)NameFileCString, ? ,0);

fileFlux.open(NameFileCString, ios::out | ios::binary);

if (fileFlux.fail())

return (-1);

else

{

while ((recv(Serveur.sockTransfert,&charLuRecu, 1,0)) != 0)

fileFlux.write(&charLuRecu, 1);

fileFlux.close();

return(0);

}

}





Faut il calculé la taille du fichier avant puis l'envoyer dans la
socket , et envoyer ensuite le nom de fichier ? ou bien y a til un
moyen plus rapide?



Merci ed'avance et merci pour la 1ere reponse sa marche en tout cas!



PS : je sais pas si je compil en unicode, comment on le sait?
Messages postés
7
Date d'inscription
lundi 14 mars 2005
Statut
Membre
Dernière intervention
10 avril 2005

Bon alors sa transfert bien mais alors niveau taille c'est un peu la galere...



j'ai l'impression que ce st totalement aleatoire...

je fais sa pour essaye de faire en sorte que sa transmette bien mais ,
quand je met un nom de fichier de 3-4 caractere et bien il complete
...et il ne touche pas le reste du fichier.

quand je met trop de caractere/ou le nombre exact de caractere, il
ecrit des caractere dans le fichier et donc la taille n'est lus bonne..

voila les codes (client et servuer)



client :

//Methode d'envoie de donnée

int CTransfert::EnvoyerDonnee(CString Chemin, CString NomFichier)

{

i = NomFichier.GetLength();

itoa(i,taille,15);

send(Client.sock, taille, sizeof(taille) , 0);



send(Client.sock, (LPTSTR)(LPCTSTR)NomFichier, i ,0);

/*Ouverture du fichier en Lecture et en mode Binaire*/

fileFlux.open(Chemin, ios::in | ios::binary);

if (fileFlux.fail())

return(-1);

//Si l'ouverture echoue, on quitte et on renvoie -1

else

{ //Tant qu'on est pas a la fin du fichier, on lit..

while ((fileFlux.read(&charLuEnvoye, 1)) != 0)

/*..et chaque caractere lu est envoyer par la socket

du client (declarer dans Transfert.h)*/

send(Client.sock, &charLuEnvoye, 1, 0);

fileFlux.close();

return (0);

//on retourne 0 lorsque tout est terminé ou si il n'y a pas d'erreur

}

/*Fermeture du fichier*/

}





Serveur :

int CTransfert::RecevoirDonnee(void)

{

int i;

recv(Serveur.sockTransfert, Taille, sizeof(Taille), 0);

i = atoi(Taille);



recv(Serveur.sockTransfert, (LPTSTR)(LPCTSTR)NameFileCString, i,0);

fileFlux.open(NameFileCString, ios::out | ios::binary);

if (fileFlux.fail())

return (-1);

else

{

while ((recv(Serveur.sockTransfert,&charLuRecu, 1,0)) != 0)

fileFlux.write(&charLuRecu, 1);

fileFlux.close();

return(0);

}

}



franchement si vous avez une solution...car je commence à saturé avec
cette histoire...je comprend vraiment pas pk sa rajoute des caractere,
un coup dans le fichier, un coup dans le nom du fichier...
Messages postés
402
Date d'inscription
mardi 1 mai 2001
Statut
Membre
Dernière intervention
15 août 2011

Personnellement, j'utiliserais un buffer/tampon temporaire pour faire les envois/réceptions avec send() & recv() ...



Pour ton:

while ( recv( ... ) != 0 )

{

}



recv() renvoie -1 en cas d'erreur, 0 si la connexion à été
`correctement` fermée et plus grand que zéro(0) si des données ont été
lus alors tu devrais plutôt faire:



int ret;

while ( (ret = recv( ... )) > 0 )

{

// ...

}

if ( ret > 0 ) puts("Good!");

else printf("Error: %d", ret);




~(.:: NitRic ::.)~
Messages postés
7
Date d'inscription
lundi 14 mars 2005
Statut
Membre
Dernière intervention
10 avril 2005

oui en effet, c'est une meilleur sécurité! :) merci.

Je le ferai mais sans le "puts" etc... car je renvoie la valeur et puis je suis avec des MFC ...lol.



Bon sinon je risque de re-poster bientot car la je chercher un moyen de
raffraichir des images de mon IHM a partir d'un thread....et je galere
comme pas possible..Je vias encore chercher par moi meme (car c'est
comme sa qu on apprend le mieux) mais si je galere encore 2-3 jours je
risque de repasser rapidement :p lol
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Au final ça marche ou il faut lire tous les posts... : )