C++ std:string en hexadécimal ?

Hello

tout est dans le titre:

le problème a la base ,c’est les nom de fichier, vu qu’on peux y mettre casiment tout et n’importe quoi… je vai tout convertir en format hexa, sa devrai alors plus poser de problème. seulment voila on dirait que c’est faux …
voila un exemple:

#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <exception>
#include <iomanip>
using namespace std;

std::string toHex(const std::string& instr)
{
using namespace std;
ostringstream oss;
oss << hex << setw(2) << setfill('0');
for(string::const_iterator i = instr.begin(); i != instr.end(); ++i)
{
if(i != instr.begin())
{
oss << ":";
}
//oss << "0x" << static_cast<unsigned short>(*i);
oss << "" << static_cast<unsigned short>(*i);
}
return oss.str();
}

int main()
{
/*
std::stringstream ss;
ss << "your id is " << std::hex << varexa;
const std::string s = ss.str();



std::cout<< s << std::endl;*/
std::cout << toHex("Ma�anaDB.pdb (codage non valide)") << std::endl;
return 0;
}

j’obtien:

je me demande si la sortie est vraiment valable car:

semble erronnée c’est lier aux caractère :
si quelqu’un a une idée je suis preneur

Merci d’avance

Je ne comprends pas très bien ton problème (j’ai pas eu le temps aujourd’hui de lire ton code).

Si c’est un problème lié à unicode, tu devrais plutôt te pencher (mais pas trop pour ne pas tomber) sur std::wstring

Je ne comprends pas très bien ton problème (j’ai pas eu le temps aujourd’hui de lire ton code).

Si c’est un problème lié à unicode, tu devrais plutôt te pencher (mais pas trop pour ne pas tomber) sur std::wstring[/quote]
ah ben je suis quand meme tomber sur …un bug :

#include <iostream>
#include <string>
#include <sstream>
#include "cScanDrive.hpp"
#include "cUtility.hpp"
#include <cstring>
#include <exception>
#include <iomanip>
using namespace std;

#include <locale>
#include <vector>




const char conn_str[] = "user='taz' password='postgresbytaz' host='127.0.0.1' dbname='ma_base'";
/*
faire une instance pour l'insertion avec le md5 avec un tread ou un fork
*/


std::string toHex(const std::string& instr)
{
using namespace std;
ostringstream oss;
oss << hex << setw(2) << setfill('0');
for(string::const_iterator i = instr.begin(); i != instr.end(); ++i)
{
if(i != instr.begin())
{
oss << ":";
}
//oss << "0x" << static_cast<unsigned short>(*i);
oss << "" << static_cast<unsigned short>(*i);
}
return oss.str();
}

std::string narrow(const std::wstring& ws)
{
    std::vector<char> buffer(ws.size());
    std::locale loc("english");
    std::use_facet< std::ctype<wchar_t> >(loc).narrow(ws.data(), ws.data() + ws.size(), '?', &buffer[0]);

    return std::string(&buffer[0], buffer.size());
}

std::wstring widen(const std::string& s)
{
    std::vector<wchar_t> buffer(s.size());
    std::locale loc("english");
    std::use_facet< std::ctype<wchar_t> >(loc).widen(s.data(), s.data() + s.size(), &buffer[0]);

    return std::wstring(&buffer[0], buffer.size());
}


int main()
{

std::wcout<< widen("Teste") << std::endl;
}

vala , mai je pense pas que l’unicode va résoudre le problème

Mon propos consistait à remplacer la méthode de l’hexagone par l’unicode. Même si je ne comprends pas bien ton besoin initial.

j’ai tenter avec l’unicode ,mai sans succès, ou alors je m’y prend de travert …

Je ne comprends pas non plus le problème initial, mais vu qu’il est question de noms de fichiers je ne vois pas pourquoi un encodage en hexa changerait quoi que ce soit.
Panthere, si tu nous expliquais ce que tu veux faire réellement ?

C’est simple j’ai des nom de fichier par exemple

/home/monser

seulement ce type de donnée on peux y mettre n’importe quoi sauf les /
j’ai donc un fichier avec un nom a la c**:

/home/monser/Ma�anaDB.pdb (codage non valide)

A stoquer dans une base de donnée ,qui est postgresql.
et la ça rale:

terminate called after throwing an instance of 'pqxx::data_exception
what():  ERREUR:  séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e6
HINT:  Cette erreur peut aussi survenir si la séquence d'octets ne correspond pas
au jeu de caractères attendu par le serveur, le jeu étant contrôlé par
« client_encoding ».

j’espérerais en codant en hexadécimale que cela résolve le problème mai pour le moment rien ne tien la route.
voila je pense que j’ai tout dit …
donc le but c’est que quelque soit le tpye utf8,héxa,byte etc je puisse y mettre dans la db de manière parfaitement identique:slight_smile:

Merci de m’avoir lu :006

Et si tu changeais bêtement le type de ta colonne dans PostgreSQL ? Au lieu de stocker une chaîne, stocke un blob. Ça contournera le problème.
Tu as VRAIMENT besoin que ça soit une chaîne dans ta base ?

[quote=“syam”]Et si tu changeais bêtement le type de ta colonne dans PostgreSQL ? Au lieu de stocker une chaîne, stocke un blob. Ça contournera le problème.
Tu as VRAIMENT besoin que ça soit une chaîne dans ta base ?[/quote]

blob n’existe pas dans posgresql … bytea semble si rapprocher mai l’echappement reste indispensable
http://docs.postgresql.fr/9.1/datatype-binary.html
peux importe comment c’est stoquer décimal etc. du moment que je puisse faire des tris avec . je peux convertir avant l’insert et après la sortie d’un select. :think:

mai là rien n’a fonctionner pour le moment…
il faut dire que j’ai de la peine a comprendre comme me servir de la lib: :017
roguewave.com/portals/0/prod … BBlob.html

si t’a un exemple je suis preneur :pray:

Tu peux configurer ta base en utf8 : postgresql.org/docs/current/ … ibyte.html
En suite en utilisant les wstring ça devrait passer.

Ben je t’avoue, je connais pas PostgreSQL. Quand je disais “blob” c’est le terme générique : une séquence d’octets, peu importe ce qu’il y a dedans. À vue de nez le type bytea semble effectivement convenir. Pour l’échappement je sais pas, encore une fois j’utilise toujours des requêtes paramétrées (on en a déjà discuté, si j’ai bon souvenir avec pqxx ils appellent ça des “prepared statements”).

[quote=“MisterFreez”]Tu peux configurer ta base en utf8 : postgresql.org/docs/current/ … ibyte.html
En suite en utilisant les wstring ça devrait passer.[/quote]
Non justement son problème c’est que la chaîne à stocker n’est pas de l’UTF-8 valide (le filesystem autorise n’importe quelle séquence d’octets sans imposer qu’elle soit compatible UTF-8).

[quote=“syam”]Ben je t’avoue, je connais pas PostgreSQL. Quand je disais “blob” c’est le terme générique : une séquence d’octets, peu importe ce qu’il y a dedans. À vue de nez le type bytea semble effectivement convenir. Pour l’échappement je sais pas, encore une fois j’utilise toujours des requêtes paramétrées (on en a déjà discuté, si j’ai bon souvenir avec pqxx ils appellent ça des “prepared statements”).
[/quote]
+1
j’utilise déja prepared, la base et le clients est en utf8 , le problème reste que c’est pas du vrai blob puisqu’il faut quand meme gerer le contenu pour faire l’échappement …

[quote]

[quote=“MisterFreez”]Tu peux configurer ta base en utf8 : postgresql.org/docs/current/ … ibyte.html
En suite en utilisant les wstring ça devrait passer.[/quote]
Non justement son problème c’est que la chaîne à stocker n’est pas de l’UTF-8 valide (le filesystem autorise n’importe quelle séquence d’octets sans imposer qu’elle soit compatible UTF-8).[/quote]
+1
sans compter les différent fs et sous unix je te dit pas le nombre de local qu’il y a …
wstring ,j’ai tester rien de concluant le problème reste.

Put*ng sa fait 4 jours que je suis dessus … je tourne en rond entre: wstring,libpqxx,unicode,bytea,hexa … :101 :angry-banghead: :angry-banghead: :angry-banghead:

Fais voir ton code (juste le prepared statement) qui correspond à une colonne bytea. À priori il faut utiliser pqxx::prepare::treat_binary lors du prepare().

pqxx.org/devprojects/libpqxx/doc … 00193.html
pqxx.org/devprojects/libpqxx/doc … 00189.html

[quote=“syam”]Fais voir ton code (juste le prepared statement) qui correspond à une colonne bytea. À priori il faut utiliser pqxx::prepare::treat_binary lors du prepare().

pqxx.org/devprojects/libpqxx/doc … 00193.html
pqxx.org/devprojects/libpqxx/doc … 00189.html[/quote]
teste le problème reste le meme:

(*p_connect).prepare("InsTprincipal",cSI.Get_InsertTPrincipal()) ("integer")("bytea",pqxx::prepare::treat_binary)("");//dernier paramettre clef auto primaire

note je les ai essayer les 3

(*p_connect).prepare("InsTprincipal",cSI.Get_InsertTPrincipal()) ("integer")("bytea",pqxx::prepare::treat_binary)("");
(*p_connect).prepare("InsTprincipal",cSI.Get_InsertTPrincipal()) ("integer")("bytea",pqxx::prepare::treat_string)("");
(*p_connect).prepare("InsTprincipal",cSI.Get_InsertTPrincipal()) ("integer")("bytea",pqxx::prepare::treat_direct )("");
//pour info
cSI.Get_InsertTPrincipal() = INSERT INTO table_principal(exist,datescan,path,keyid) VALUES ($1,$2,$3,default)

la collonne est bien en bytea ,verifier avec pgadmin3
y a pas a dire je suis coincer la dessu … fait ch…

Et avec pqxx::transaction_base::esc_raw(), toujours en utilisant treat_binary pendant le prepare ? (avec pqxx::binarystring pour relire la valeur lors d’un SELECT)

C’est un coup à me faire taper sur le doigts…

Purée! J’entrave pas un mot de votre discussion! :005
(y’a juste string qui me fait quand même penser à quelque chose… et encore, en hexadécimal j’ai du mal à visualiser…)

:laughing: :arrow_right:

[quote=“lol”](y’a juste string qui me fait quand même penser à quelque chose… et encore, en hexadécimal j’ai du mal à visualiser…)

:laughing: :arrow_right:[/quote]

:laughing: :laughing: :005 :005

bon j’ai fait l’insert , tu peux me dire comment je tourne ton binarystring dans ma boucle ?

//const int bufSize = 1;
char buffer1[35]="Ma�anaDB.pdb (codage non valide)"; // some raw data
buffer1[0] = 0x89;

const std::string Esc = (*p_connect).esc_raw(reinterpret_cast <const unsigned
char *> (&buffer1), 2);
*p_work).prepared("InsTprincipal")(exist)(datescan)(Esc).exec();

sa passe mai avec:

*p_work).prepared("InsTprincipal")(exist)(datescan)(Esc).exec();

c’est lier aux buffer1 le style C c’est … :doh:

pour la relecture du select un ptit coup de main ? :006


    for (pqxx::result::const_iterator cit = r.begin();
         cit != r.end();//boucle sur le nombre de tuple (ligne renvoiyée)
         ++cit)

		//boucle sur les collonnes
		for (unsigned int countcol = 0; countcol < r.columns();countcol++){

//j'affiche avec (enfin presque )
//              std::cout <<(*cit)[countcol].as(int ()) << deco ;
              std::cout <<(*cit)[countcol].c_str();

c’est vraiment ce qu’on veux :S
je cherche encore dans la doc mai rien pour le moment.

c’est vraiment ce qu’on veux :S[/quote]
Bah oui. Lorsque tu stockes, ton premier caractère est 0x89 (décimal 137, octal 211), le deuxième a, et tu indiques à esc_raw de ne prendre en compte que les deux premiers caractères : esc_raw(… , 2);
Si tu veux stocker l’intégralité de ta chaîne il faudrait peut-être indiquer la bonne longueur. :wink:

Dans ta boucle for tu ne peux pas traiter toutes les colonnes de la même manière !
Si tu tiens absolument à utiliser une boucle, il faut traiter ta 3ème colonne (index 2 comme on part de zéro) différemment (je pars du principe que “AFFICHE1” ne fait pas partie des résultats) :

for (unsigned int countcol = 0; countcol < r.columns(); ++countcol) { std::string valeur; if (countcol == 2) valeur = pqxx::binarystring((*cit)[countcol]).str(); else valeur = (*cit)[countcol].c_str(); std::cout << valeur; }
Perso j’aime pas trop cette manière de faire, je préfère extraire les valeurs de chaque colonne de manière explicite dans des variables séparées (ce qui implique aussi d’indiquer les champs de manière explicite dans le SELECT – ça exclut donc les requêtes de type SELECT * FROM… dont le résultat change en fonction du schéma de la table):

bool exist = (*cit)[0].as<bool>(); // peut-être même pas besoin d'indiquer la spécialisation, elle devrait être inférée grâce au lhs => bool exist = (*cit)[0].as() à tester std::string datescan = (*cit)[1].as<std::string>(); // même remarque std::string path = pqxx::binarystring((*cit)[2]).str();
Sinon tu peux aussi garder ta boucle for et te baser sur le type de la colonne (*cit)[colonne].type() afin de traiter ça dans un switch…

Bon Zalor vala ce que sa donne .
je met que l’utile
edit petite modification :

char my_str[]="Ma�anaDB.pdb (codage non valide)";
int l_my_str = sizeof(my_str);
//buffer1[0] = 0x89;

const std::string Esc = (*p_connect).esc_raw(reinterpret_cast <const unsigned
char *> (&my_str), l_my_str);

const std::string Esc = (*p_connect).esc_raw(reinterpret_cast <const unsigned
char *> (&buffer1), 37);

(*p_work).prepared("InsTprincipal")(exist)(datescan)(Esc).exec();
// j'affiche donc la valeur avec la bonne collonne celle qui donc a la valeur qui nous interesse,
//je supose que .c_str() devrai faire l'affaire seulement .....
std::cout <<(*cit)[countcol].c_str() << deco ;

sa donne a l’execution:

 Ma\357\277\275anaDB.pdb (codage non valide)\000

euh je comprend rien la je doit dire ?? :017