Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [sf::Int64] comment transformer un char* en sf::Int64 ?  (Lu 4037 fois)

0 Membres et 1 Invité sur ce sujet

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
[sf::Int64] comment transformer un char* en sf::Int64 ?
« le: Août 04, 2012, 06:20:01 pm »
Bonjour à tous et à toutes :)

J'utilise l'API MySQL C pour récupérer des données dont des BIGINT. Je voudrais stocker ce BIGINT dans un sf::Int64. Ma première solution était tout simplement d'utiliser atoi();, car j'utilisais des int avant. Le problème est que 2 milliards (ou 4 en Uint) ne suffise pas nécessairement à stocker par exemple l'argent du joueur. Je dois donc implémenter le tout avec des Int64. Le problème, c'est que l'API me retourne des char*. Or, il n'Existe pas (pas trouvé sur cplusplus.com non plus) à ma connaissance de fonction ato64i();.

Comment puis-je convertir un tableau de char en sf::Int64 ?

Merci et bonne journée 8)

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #1 le: Août 04, 2012, 06:33:46 pm »
Ah et petite question comme ça : comment se fait-il que les sf::Int32 sont capables de stocker le nombre 1 000 000 000 000 ? (1 billion) parce que je viens d'essayer tout simplement en laissant les Int32 et le nombre de la BDD est correctement inséré dedans alors qu'il défonce largement la taille du Int32 (int) qui est de 2 milliards...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #2 le: Août 04, 2012, 11:01:07 pm »
Regarde du côté des fonctions C++ plutôt que des vieux trucs du C ;)

char* le_big_int = ...;
sf::Int64 x;

std::istringstream iss(le_big_int);
iss >> x;

Citer
Ah et petite question comme ça : comment se fait-il que les sf::Int32 sont capables de stocker le nombre 1 000 000 000 000 ?
Il ne le sont pas, il y a forcément un truc qui cloche dans ton test.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #3 le: Août 05, 2012, 05:48:24 am »
Haha j'ai rien dit... Je sais pas pourquoi mais le seul champ que je modifiait et bien c'Est là que j'avais envoyé directement le row à cout... ::)

Merci pour le standard C++. Je n'y suis pas vraiment renseigné, je devrais sûrement aller lire un peu de doc à propos de cela :)
« Modifié: Août 05, 2012, 05:54:55 am par neo007 »

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #4 le: Août 05, 2012, 06:14:33 pm »
Bon, c'est super sympathique les istream et ses descendants, mais ça demande plus de place inutilement dans les cas où les vieilles fonctions font tout à fait l'affaire non ? (je veux dire que ça va demander une ligne de déclaration au début et une ligne ss.str() à chaque donnée que je dois entrer + des coups de ss.clear() à chaque fois puisque ss.str() change complètement le flux et non pour ajouter un second flux... Y a-t-il un autre truc similaire au packet dans le fond qui permet d'entrer et de sortir des flux comme on veut ?)
gi.canBreak = atoi(row[SQLDataItem::CanBreak]);
 

canBreak n'étant qu'un simple booléen et c'est la même chose pour plusieurs variables (dont plusieurs Int32 qui n'ont pas besoin d'être des Int64).

Donc devrais-je toujours utiliser un objet pour effectuer n'importe quelle conversion (au lieu de atoi, atof, etc.) ou les utiliser simplement dans le cas où les autres fonctions ne font pas l'affaire (atoi ne fonctionne pas pour du 64 bits par exemple) ?
« Modifié: Août 05, 2012, 06:36:56 pm par neo007 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #5 le: Août 05, 2012, 06:41:32 pm »
Il ne faut pas voir les choses comme ça. On s'en fiche un peu de savoir si tu appelles une fonction ou bien si tu instancies un objet ; ou encore si tu as besoin de 3 lignes au lieu d'une.

Ce qui compte c'est d'utiliser du code C++ standard. Evidemment, si tu fais ce genre de conversion 1000 fois par seconde, on pourra en reparler, mais je ne pense pas que ce soit le cas :)

Si ça peut calmer tes angoisses, tu peux toujours faire ça :
template <typename T>
T str_to(const char* str)
{
    T x;
    std::istringstream iss(str);
    iss >> x;
    return x;
}

sf::Int32 value = str_to<sf::Int32>("54");
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #6 le: Août 05, 2012, 08:14:20 pm »
Ah oui effectivement je trouve que ça ferait plus propre merci :)

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #7 le: Août 05, 2012, 09:43:40 pm »
Et faire un static_cast<sf::Int64>() ça fonctionnerait ? (juste pas curiosité parce que je vais pas rechanger deux fois toutes mes variables qui utilisaient des atoi ou atof :P)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #8 le: Août 05, 2012, 10:12:40 pm »
Citer
Et faire un static_cast<sf::Int64>() ça fonctionnerait ?
Bien sûr que non, sinon on ne se ferait pas ch*** avec des stringstreams ;)

Ca compilera, mais tu auras juste converti la valeur du pointeur en entier, pas le contenu de la chaîne.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #9 le: Août 15, 2012, 03:04:46 am »
Petite question :

Packet& operator <<(Packet& packet,const Int64 i)
{
    Uint32 ui1 = ((Uint32*)&i)[0];
    Uint32 ui2 = ((Uint32*)&i)[1];
    packet << ui1 << ui2;
    return packet;
}
 
warning: dereferencing pointer '<anonymous>' does break strict-aliasing rules
 

C'est une solution qu'on m'a donné pour envoyer un Int64 sur le réseau étant donné que la surcharge n'existe pas dans Packet.hpp. Est-ce vraiment grave ce warning ? Y a-t-il une meilleure méthode faire ?

Merci et bonne journée ! ;D

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [sf::Int64] comment transformer un char* en sf::Int64 ?
« Réponse #10 le: Août 15, 2012, 10:35:10 am »
C'est "grave" pour plusieurs raisons :
- tu casses une règle du C++ (même si tu ne comprends pas forcément ce que ça implique, ça ne sent déjà pas bon), donc le résultat n'est pas garanti à 100%
- tu vas inévitablement te heurter à des problèmes d'endianness

Je te conseille plutôt ça :
Packet& operator <<(Packet& packet,const Int64 i)
{
    Uint32 ui1 = static_cast<Uint32>(i >> 32);
    Uint32 ui2 = static_cast<Uint32>(i & 0xFFFFFFFF);
    packet << ui1 << ui2;
    return packet;
}

Packet& operator >>(Packet& packet, Int64& i)
{
    Uint32 ui1, ui2;
    packet >> ui1 >> ui2;
    i = (static_cast<Int64>(ui1) << 32) | ui2;
    return packet;
}
Laurent Gomila - SFML developer

 

anything