• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 473
  • Last Modified:

__int64 data exchange, for Answers2000

Hi again,

I deleted the old question because I have it narrowed to this:

void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, __int64& value)
  if (pDX->m_bSaveAndValidate)
    DDX_TextWithFormat (pDX, nIDC, _T("%I64d"), AFX_IDP_PARSE_INT, &value);
    DDX_TextWithFormat (pDX, nIDC, _T("%I64d"), AFX_IDP_PARSE_INT, value);

Why doesn't that work?  The format strings appear correct.  What am I doing wrong?  I have increased the points to 75 since you have helped me so much on the rest of the parts of the question.  Feel free to answer this time, as I know you know :)
1 Solution
Hi gosh

I've been thinking about this...

%l64d is the wrong format string, as you realized.

1. I think you meant

This is a 64 char wide "ld"
Unfortunately ld means long int = 32 bits

2. Unfortunately in VC5 I have discovered support in the runtime library for int64 is basically (almost) not existent.  Maybe it's better in VC6 (I don't have it so can't check).

Fortunately I have discovered two funcs you can use

_atoi64 - convert a string to 64 bit integer, example:

__int64 x = atoi64( string ) ;

_i64toa - convert 64 bit int to string, example:

char string[256] ;
i64toa( value /* 64 bit int */, string, 10 ) ; // 10 means base 10

3. As far as I can see scanf/printf don't have support for 64 bit int's.  So unfortunately I have mislead you a bit in my previous comments.  Take a copy of DDX_TextWithFormat into your code, rename it, and replace conversion code using scanf/printf with the runtime library code I gave in #2.  Your version won't need the 3rd or 4th params, or variable argument stuff, something like:

static void AFX_CDECL My_DDX_TextWithFormat(CDataExchange* pDX, int nIDC, __int64& i64
      HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);

              TCHAR temp[32]
      if (pDX->m_bSaveAndValidate)
            ::GetWindowText(hWndCtrl, temp, _countof(temp));
                            i64 = atoi64( temp ) ;
                             // see my note below
                            if ( ( i64 == 0) && ( !ValidZero( temp ) )
                  pDX->Fail();        // throws exception
                            i64toa( i64/* 64 bit int */, temp, 10 ) ; // 10 means base 10
                            ::SetWindowText( hWndCtrl, temp ) ;

Couple of things to note on the above

(i) I don't know if this works in Unicode - i haven't tried i64toa and atoi64 in unicode.  It should be okay for a normal ANSI compiled program

(ii) atoi64 returns 0 for a bad string (e.g. one with letters).  This means if the user enters a bad string you need to read and check the string yourself as the correct format.  As you know 0 is the only possible bad string, you can check this easily but writing a function to valid strings which mean 0, really are 0 and not so bad string, example:

// This function checks a string returns by atoi64 as 0, really is zero and not some bad
// string
BOOL ValidZero( const char * psz )
  int ll = strlen( psz ) ;
  if ( ll == 0 ) return FALSE ; // empty string - is an error

  // 0 string should only contain 0 and spaces
  // it should also contain only one zero
  int zerocount = 0 ;
  for ( int ii = 0 ; ii < ll ; ii++ )
     if ( ( psz[ii] != '0' ) && ( psz[ii] != ' ' ) ) return FALSE ;
     if ( psz[ii] == '0' ) zerocount++ ;
  } // for ii

  return (zerocount == 1 )  ;

goshAuthor Commented:
That has fixed my problem entirely!  It works great now.  Everything works.  Thank you very much!
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now