views:

1210

answers:

5

We have a file that has a 64 bit integer as a string in it. How do we scanf() or otherwise parse this numeric string into an unsigned 64 bit integer type in C++ ?

We are aware of things like %lld etc., but a lot of ways to do this parse seem to break compiles under different compilers and stdlibs. The code should compile under gcc and the Microsoft C++ compiler (of course full compliance with standards would be a plus)

A: 

Don't use scanf(), tokenize your input separately and then use strtoull() or similar.

Alnitak
Is strtoull() supported on Windows natively?
Thorsten79
You can quite easily make your own.
Artelius
To be fair, I did say "or similar" :)
Alnitak
+1  A: 

Alnitak recommends strtoull(), but it seems it's not available in Win32 environments. The linked-to forum thread recommends either of _strtoui64(), _wcstoui64() and _tcstoui64() as replacements. Perhaps this is "on the edge" of stuff that can't really be done with a single portable function call, and you might need to implement different code paths for different platforms. Or, I guess, write your own ASCII-to-64-bit converter, it's not rocket science.

unwind
+3  A: 

Or use the typesafety of istream...

  using namespace std;

  // construct a number -- generate test data
  long long llOut = 0x1000000000000000;
  stringstream sout;
  // write the number
  sout << llOut;
  string snumber = sout.str();
  // construct an istream containing a number
  stringstream sin( snumber );

  // read the number -- the crucial bit
  long long llIn(0);
  sin >> llIn;
xtofl
+2  A: 

std::fstream fstm( "file.txt" );

__int64 foo;

fstm >> foo;

RobH
+5  A: 

GCC has long long, as will compilers for C++0x. MSVC++ doesn't (yet), but does have its __int64 you can use.

#if (__cplusplus > 199711L) || defined(__GNUG__)
    typedef unsigned long long uint_64_t;
#elif defined(_MSC_VER) || defined(__BORLANDC__) 
    typedef unsigned __int64 uint_64_t;
#else
#error "Please define uint_64_t"
#endif

uint_64_t foo;

std::fstream fstm( "file.txt" );
fstm >> foo;
KTC
Personally, I'd use uint64_t from stdint.h. It's a C99 standard, not C++, but it's in GCC and you can easily find VC++ versions online and bung them in your project. Same goes for J. Random platform in future, and if we're lucky it'll be in C++0x.
Steve Jessop
It is in C++0x. Though (u)int64_t is actually optional, one can safely assume it will be available for PCs. Otherwise, one can use uint_least64_t or uint_fast64_t.
KTC