Hi All,


i have a problem in converting CString to Int/Double,
function i am using is _wtoi , _wtof.....
Here if the CSting value has say "12345"
this works perfectly. But if any other value is say ( Over flow )
" 11111111111111111111111111111" which exceeds
the max size of int then it returns INT_MAX, where as i need the
exact string as int ie 11111111111111111111111111111 in the integer variable. same thing happens in double.

if there is any junk value entered then the ret value is 0,
Please help me in converting the CString to exact int value

Dani AI

Generated

was right: a fixed-size C integer simply cannot hold an arbitrarily long decimal string. Functions like _wtoi / _wtof are convenience CRT helpers with very limited error signaling — they can return 0 for non‑numeric input or return extreme values and set errno = ERANGE on overflow. correctly noticed errno getting set; clearing errno before the next conversion will "fix" the symptom, but that pattern is brittle and easy to misuse.

Prefer explicit, modern conversions that report errors. In C++ (C++11 and later) std::stoll / std::stoull and std::stod / std::stold throw std::invalid_argument for non-numeric strings and std::out_of_range for overflow, so they cleanly distinguish cases:

std::wstring s = static_cast<LPCTSTR>(cstr); // or cstr.GetString()
try {
    long long v = std::stoll(s);
    double d = std::stod(s);
    // use v or d
} catch (const std::invalid_argument&) {
    // not a number
} catch (const std::out_of_range&) {
    // value doesn't fit target type
}

If sticking to C-style APIs, use wcstoll / wcstod with an end-pointer plus errno checks: set errno = 0 immediately before the call, check whether the end-pointer advanced (no advance => no conversion), and treat errno == ERANGE as overflow. That combination is robust because it detects both invalid input and range errors; resetting errno is common but should be done immediately around the conversion and checked immediately after.

If the goal is to preserve every digit (the sample long string), store the value as a string or use an arbitrary-precision library (for example Boost.Multiprecision cpp_int or cpp_dec_float) — built-in int/long long and double cannot hold arbitrarily many digits (doubles also only have about 15–17 decimal digits of precision). A simple way to build a big integer from a decimal string is to multiply-accumulate digits into a cpp_int.

Checklist: keep huge values as strings or use BigInt if exact value is required; use std::stoll/std::stod for clear error handling; use wcstoll/wcstod + endptr+errno if C APIs are required.

Recommended Answers

All 2 Replies

There isn't much you can do about overflows, except just discard the bad CString value. It returns INT_MAX because its impossible to put that many digits into an int variable. I'd like to stuff my 100 inch waste into size 36 slacks too, but that's not possible either :)

Finally i found a way...
When ever any over flow occurs a global variable errno get's set to ERANGE so in the code i have made a check like this

int ConvertToInt( CString intVal )
{
       int ret = _wtoi(intVla);
       if((ret == 0) || (errno == ERANGE))
       {
               // Throw Exception
               // I dont know why i have to do this
               errno = 0;
               // If i dont reset the "errno" then the value will be set to   
                     //ERANGE even if the next string is valid
           //I dont know resetting the system variable is correct or not.
               // Functionality works for me :)
       }
}

Resetting would give any side effects ?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.