2011-04-22 2 views
3

Je suis donc en train de faire une conversion d'une chaîne en strtoul long non signé sur un petit boutiste et un gros boutiste. La petite machine d'Endian renvoie la valeur correcte, tandis que la grosse machine d'Endian ne le fait pas. Cette fonction est-elle vraiment incompatible avec les grosses machines endian? Si oui, y a-t-il un travail?est strtoul pas endian sécuritaire?

code:

printf ("%s\n",cLongs); 
theLongs[i] = strtoul(cLongs, NULL, 10); 
cout << "returned unsigned long value from string: " << theLongs[i] << endl; 

Petit résultat endian:

1099188638048931 
returned unsigned long value from string: 1099188638048931 

résultat Big Endian:

1099188638048931 
returned unsigned long value from string: 4294967295 

post-scriptum Il semble que le même nombre est toujours retourné pour l'exemple Big endian.

Répondre

4

strtoul renvoie ULONG_MAX en cas de dépassement. C'est ce que tu frappes. Je suppose que l'un fonctionne sur 32 bits l'autre sur 64 bits en plus des différences Endianess. 4294967295 == 0xFFFFFFFF, qui pour une machine 32 bits serait ULONG_MAX.


Essayez si ce qui suit fonctionne pour vous sur les deux systèmes. Je n'ai pu le tester que sur un Little Endian Linux 64 bits. Si oui, vous pouvez utiliser les flux de chaîne pour la conversion (qui est de toute façon le C++ style à faire des choses):

#include <iostream> 
#include <sstream> 

int main() 
{ 
    using namespace std; 
    string sval("1099188638048931"); // your huge value, exceeding 32bit 
    istringstream sst(sval); // assign string to a stream 
    unsigned long long myval; 
    sst >> myval; // convert stream to unsigned 64bit integer 
    cout << myval << endl; // output the converted result 
    return 0; 
} 

Notez que unsigned long long faudrait être unsigned __int64 avec MSVC. D'autres compilateurs peuvent avoir d'autres noms. Si vous êtes chanceux, vous aurez standard types sur toutes vos plates-formes et pouvez utiliser uint64_t ...

+0

Cela semble être la bonne réponse après avoir essayé un plus petit entier non signé. Y at-il moyen de contourner ce problème ou suis-je coincé entre un rocher et un endroit difficile? –

+0

@Jeff: Je suis à peu près sûr qu'il n'y a pas de solution qui fonctionne sur plusieurs plates-formes, car ce serait au-delà de la norme C. Mais au lieu de l'exécution C, vous pouvez utiliser le flux de chaîne C++ et l'opérateur '<<' pour extraire une valeur entière plus grande. Je suis sûr que C++ devrait être préparé pour cela. Je verrai si je peux vous obtenir un petit exemple piraté ensemble. Donne aussi la réponse si C++ est préparé ou pas :) – 0xC0000022L

+0

@Jeff: voyez si vos systèmes ont 'strtoull' (' strtouq' sur BSD), qui utilise 'unsigned long long' - probablement 64 bits sur les deux. –

Questions connexes