The digital conversions in C, C + +, C + + / CLI PDF Print E-mail
User Rating: / 0
PoorBest 
Wednesday, 14 May 2008

I. Problem Definition
As I said in the introduction conversion between string and native type is central to our programs,
Checks Windows work with strings but may represent a digital recording see decimal.
The internal representation of these visual data are most often stored internally in their native type,
Just then to raise the problem of conversion between control and variable.

The majority of posts related to our forums often boils down to these questions:
How to convert a chain-wide, double, float etc. ..
How to format a string from a wide, double, float etc. ..
How to get a full, double float, and so on., From a control, and of course the reverse will be to update the control from a native type.

To proceed we have several techniques from different libraries:
Those of C, the standard library of C + +, but also some interesting contributions to the project BOOST.
I also paid attention to what all the codes operate UNICODE.
Finally I could not ignore the C + + / CLI, therefore, I shall devote a section for two-way conversion.
That is what we'll find out now.

II. Transformation of a CString or content of control to a native type

A. The Library C
The C library provides a set of features that enable the transformation of a string data type and vice versa.
A post-General is enshrined in the faq Visual C + +, so I will not dwell above, I prefer to give priority to the processing C + + Topic:
How to convert a CString int, double, long?

B. From the side of the MFC
The MFC as API 32 with GetDlgItemInt allow recovery of the contents of a form of control over.
but what about other types of long, float, double?
For these other types should be attached to control a variable corresponding data type you want and call the method UpdateData (TRUE) to have its value.

Let's now a method of transforming a string in his native type implementing the standard library C + + (standard library).

C. The standard library of C + + (SL)
We begin by converting a string to a type specified:

# include <string>
# include <iostream>
# include <sstream>

template <typename T,typename S>
bool FromString (const S & Str, T & DEST)
(
# ifdef _UNICODE
     std:: wistringstream iss (Str);
# else
Std:: istringstream iss (Str);
# endif
     / / Try conversion to Dest
     iss return>> Dest! = 0;
)

Use:

int nInt;
FromString (_T ( "10"), nInt) / / int conversion.

dDouble double;
FromString (_T ( "3.14107"), dDouble) / / conversion to double

CString str = _T ( "1200");
# ifdef _UNICODE
Std:: wstring strstl;
# else
Std:: string strstl;
# endif

strstl = _T ( "1200");
int n = 0;
FromString (str.GetString (), n);
n = 0;
FromString (strstl, n);

The version linked to a control MFC:
The recovery of the contents of control in its native type: integer, double, float, long does not cause more problems by amending the code a bit back then:

# include <sstream>
# include <string>
# include <iostream>

template <typename T>
bool FromCtrl (const CWnd & Control, T & DEST)
(
     CString Str;
     Ctrl.GetWindowText (Str);
# ifdef _UNICODE
     std:: wistringstream iss (static_cast <LPCTSTR> (Str));
# else
std:: istringstream iss (static_cast <LPCTSTR> (Str));
# endif
     / / Try conversion to Dest
     iss return>> Dest! = 0;
)

/ / Use:

double d;
FromCtrl (* GetDlgItem (IDC_EDITNOM), d);
if (d == 10.0)
(
/ / Treatment
)
/ / Etc ...

These examples are based on the class istringstream and use overloaded operator>> to make the conversion.
This type of function is called function model, it will remain generic compared to T-type used.

D. The Project BOOST
Now let's see what the draft proposes BOOST:
It provides a class conversion lexical_cast which allows the conversion of chains representative numbers in base 10.

To use the example that follows, you will need to download the project BOOST available on SourceForge The latest version is the stable 1.33.1
You can also use the graphic version distribution BOOST with a tool distributed by Boost Consulting, see also the tutorial Install and use Boost in Windows with Visual C + + 2005
We begin by converting a string to a type specified:
The use of lexical_cast is daunting simplicity:

# include <string>
# include <boost/lexical_cast.hpp>
int n, n1, n2;
CString str = _T ( "1200");
# ifdef _UNICODE
Std:: wstring strstl;
# else
Std:: string strstl;
# endif
Strstl = _T ( "1200");
     try
(
n = boost: lexical_cast <int> (static_cast <LPCTSTR> (str));
N1 = boost: lexical_cast <int> (strstl);
N2 = boost: lexical_cast <int> (_T ( "1200"));
)
Catch (boost: bad_lexical_cast & e)
(
# ifdef _DEBUG
TRACE ( "Bad conversion:% s", static_cast <const char *> (e.what ()));
# endif
Return false;
)

No need to flow, the sequence can be used directly.
Nevertheless, we can always encapsulate treatment at a function model:

# include <string>
# include <boost/lexical_cast.hpp>
template <typename T,typename S>
bool BoostFromString (const S & rStr, T & DEST)
(
     try
(
Dest = boost: lexical_cast <T> (rStr);
)
Catch (boost: bad_lexical_cast & e)
(
# ifdef _DEBUG
TRACE ( "Bad conversion:% s", static_cast <const char *> (e.what ()));
# endif
Return false;
)
Return true;
)

The same example will:

int n = 0;
/ / MFC
CString str = _T ( "1200");
BoostFromString (str.GetString (), n);
/ / C + + - STL: string
# ifdef _UNICODE
Std:: wstring strstl;
# else
Std:: string strstl;
# endif
strstl = _T ( "1200");
BoostFromString (strstl, n);
/ / String
BoostFromString (_T ( "1200"), n);

The version linked to a control MFC:

template <typename T>
bool BoostFromCtrl (const CWnd & Control, T & DEST)
(
     CString Str;
     Ctrl.GetWindowText (Str);
     try
(
Dest = boost: lexical_cast <T> (static_cast <LPCTSTR> (Str));
)
Catch (boost: bad_lexical_cast & e)
(
# ifdef _DEBUG
TRACE ( "Bad conversion:% s", static_cast <const char *> (e.what ()));
# endif
Return false;
)
Return true;
)

Use:

int n = 0;
BoostFromCtrl (* GetDlgItem (IDC_EDITNUM), n);

Through these examples we found different techniques to convert a string to a digital format, control of the conversion, with the various libraries.
For my part I find the use of boost: lexical_cast more attractive as very simple and usable directly.

E. The C + + / CLI
In C + + / CLI converting a string managed (String) in whole or double is relatively simple:

# include "stdafx.h"

using namespace System;

int main (array <System::String ^> ^ args)
(
     String str = ^ L "1200.20";
     double d;
     int n;
     try
     (
         Console: Write (L "Tentative double conversion");
         d = Convert: ToDouble (str);
         Console: Write (L "d");
         Console: WriteLine (d);
    
         Console: Write (L "Tentative conversion Integer");
         n = Convert: ToInt32 (str); / / causes a mistake!.
         Console: Write (L "n");
         Console: WriteLine (n);
     )
     catch (e ^ FormatException)
     (
         Console: Write (e-> Message);
     )
     return 0;
)

It is the functions of conversions in the namespace System:: Convert.
The conversion to double or int does not cause particular problems.
In case of invalid a chain FormatException exception is lifted, as is the case here with my example at the attempted conversion of the entire chain.
Another example implementing conversions between:

String bin = ^ L "1111";
int decimal = Convert: ToInt32 (bin, 2);
String ^ hexa = Convert:: ToString (decimal, 16);
Console: WriteLine (L "binary = (0) \ ndécimal = 1) (\ nhexadécimail = (2)", bin, decimal, hex);

your needs or situation.

III. Conversion of a type int, long, float, double to a string
Turning now to reverse the exercise is to take a value of a native type and transform it into a string intended to update control.
A. The Library C
Basically we can use the sprintf, or functions associated with the type of data: as itoa to convert an int to a string.
Once the chain will update on control.

B. From the side of the MFC
The class CString helps us in the conversion by proposing a method Format operating in the same way that the function vsprintf, sprintf C. This example of the faq Visual shows how to use it: How to convert an integer, a double, a float, etc, to string?
Also with a view to update directly control,
For other types should be attached to control a variable corresponding to the native type desired and call the method UpdateData (TRUE) to have its value.

C. The standard library of C + + (SL)
As previously, the code that follows can happen to the association of a variable to control and therefore directly affect the value of a type native to the designated control.

# include <sstream>
# include <string>
# include <iomanip>
# include <iostream>

class FormatNum
(
public:
FormatNum () ()
Template <typename T>
FormatNum (const T & t)
(
Operator <<(t);
)
Template <typename T>
     FormatNum & operator <<(const T & t)
     (
         m_ss <<t;
         * return this;
     )

public:
# ifdef _UNICODE
Std:: wstringstream m_ss;
# else
Std:: stringstream m_ss;
# endif
);

template <typename T>
void ToCtrl (CWnd & Ctrl, const T & Src, FormatNum & rFormat = FormatNum ())
(
RFormat <<Src;

# ifdef _UNICODE
Std:: wstring s = rFormat.m_ss.str ();
# else
Std:: string rFormat.m_ss.str s = ();
# endif
     Ctrl.SetWindowText (s.c_str ());
)

Use:

/ / Met 10,345 in control.
ToCtrl (* GetDlgItem (IDC_EDITNUM), 10,345);
/ / Met in 10.35 control.
ToCtrl (* GetDlgItem (IDC_EDITNUM), 10,345,
FormatNum () <<std:: setprecision (4));

The treatment is divided into two parts:
The function ToCtrl model capable of processing user type and placement of the chain control past argument.
An object FormatNum optional feature that allows formatting the feed to control the conversion, the sequence of arguments, and which provides the subject flow conversion of Class stringstream the function model ToCtrl.

Let's use in the following examples:
In the case of a double or float if you want to master the accuracy of the number sent will use the setprecision defined in the header iomanip standard for determining the number of digits desired.
You can of course use the other functions and complement the flow
Examples:
Controlling the length of the chain created, and specify a filling.

/ / Gives 0000010.35
ToCtrl (* GetDlgItem (IDC_EDITNUM)
10,345,
FormatNum () <<std:: setprecision (4) <<std:: setfill (_TCHAR ('0'))<< std:: setw (10));

This example imposes an accuracy of 4 digits, a chain of 10 characters filled with'0 '.
In the same vein we can fix the base conversion ...

/ / Gives 0000000020
ToCtrl (* GetDlgItem (IDC_EDITNUM)
32,
FormatNum () <<std:: setprecision (4) <<std:: setfill (_TCHAR ('0'))<< std:: setw (10) <<setbase (16));

Finally add the text before the conversion:

/ / Gives: Conversion Hexa: 0x0000000020
ToCtrl (* GetDlgItem (IDC_EDITNUM)
32,
FormatNum ()<<_ T ( "Conversion Hexa: 0x") <<std:: setprecision (4) <<std:: setfill (_TCHAR ('0'))<< std:: setw (10) <<setbase ( 16));
/ / or
ToCtrl (* GetDlgItem (IDC_EDITNUM)
32,
FormatNum (_T ( "Hexa Conversion: 0x "))<< std:: setprecision (4) <<std:: setfill (_TCHAR ('0'))<< std:: setw (10) <<setbase (16) );

Or a more airy syntax:

FormatNum format;
format <<_T ( "Hexa Conversion: 0x") <<std:: setprecision (4) <<std:: setfill (_TCHAR ('0'))<< std:: setw (10) <<setbase (16) ;

ToCtrl (* GetDlgItem (IDC_EDITNUM), 32, format) / / gives: Conversion Hexa: 0x0000000020

You also notice the use of the optional specification of format conversion (FormatNum).
It will complement our treatment by a conversion function to a CString or string of STL.


template <typename T,typename S>
void ToString (S & rstr, const T & Src, FormatNum & rFormat = FormatNum ())
(
RFormat <<Src;
# ifdef _UNICODE
Std:: wstring s = rFormat.m_ss.str ();
# else
Std:: string rFormat.m_ss.str s = ();
# endif
Rstr s.c_str = ();
)

Use:

CString str;
ToString (str, 1200);
# ifdef _UNICODE
Std:: wstring strstl;
# else
Std:: string strstl;
# endif
ToString (strstl, 1200);

D. The Project BOOST
BOOST provides Boost Format library containing a class format to achieve conversions, the more it allows the format specifications as printf C.

try
(
# ifdef _UNICODE
boost: wformat f (_T ( "% 1% is way%% 2% 3 %"));
# else
boost: f format ( "% 1% is way%% 2% 3%");
# endif
F% 1;
F% _T ( "see")% _T ( "things");
AfxMessageBox (boost: io: str (f). C_str ());

f.clear () / / clear the buffer before reuse ...

F.parse (_T ( "entire conversion% d"));
F% 1200;

AfxMessageBox (boost: io: str (f). C_str ());

# Ifdef _UNICODE
GetDlgItem (IDC_EDITNUM) -> SetWindowText (boost: io: str (boost: wformat (_T ( "Hexa Conversion: 010x%"))% 32). C_str ());
# Else
GetDlgItem (IDC_EDITNUM) -> SetWindowText (boost: io: str (boost: format ( "Hexa Conversion: 010x%)% 32). C_str ());
# Endif
)
catch (boost: io: format_error & e)
(
TRACE ( "Bad conversion:% s", static_cast <const char *> (e.what ()));
)

Boost Format can be used several ways (examples above).
-- In lieu of arguments: each number surrounded by% must be replaced using opèrateur%.
-- By specifying a format: We will then use the same format specifications available with the printf function of C.
I have shown that two aspects of this library has many possibilities.
Do not hesitate to consult the online documentation associated with the examples: http://www.boost.org/libs/format/index.html

Interest Boost Format MFC in a project may seem more limited since we have the method format class CString.
It will be much more useful in projects C + + standards, or in achieving libraries to happen in MFC.

D. The C + + / CLI
The conversion of a type native to a string occurs naturally in C + + / CLI:

# include "stdafx.h"
using namespace System;
 
int main (array <System::String ^> ^ args)
(
 
Double d = 3.14107;
     int n = 100;
     String ^ Str;
     Console: Write (L "Conversion double chain:");
     Str = d.ToString ();
     Console: WriteLine (Str);
 
     Console: Write (L "Conversion int chain:");
     Str = n.ToString ();
     Console: WriteLine (Str);
 
     Console: WriteLine ((12356). ToString ());
     Console: WriteLine ((0xFF). ToString ());
     Console: WriteLine ((true). ToString ());
)

d.ToString () deserves some explanation:
In C + + / CLI all types classics are aliases object of the framework. Net, an int is therefore an object that inherits the class System:: Object.
It has (among others) the method ToString () that converts the object string.
Another advantage in C + + / CLI types are classical objects they are initialized to zero.

Another interesting possibility which is demonstrated in the last lines of my example:
A literal digital can be regarded as an object if it is surrounded by parentheses, then the ToString method can be applied…

This type of conversion has the advantage of being simple but it does control the format of the chain obtained.
It will then use String:: Format.

     using namespace System;
     using namespace System: Globalization;
 
     Str = String:: Format (CultureInfo: CurrentCulture,
         "(C) Currency:........ (0: C) \ n" +
         "(D) Decimal:......... 0,4:0 () \ n" +
         "(E) Scientific:....... (1: E) \ n" +
         "(F) Fixed point:....... (1: F) \ n" +
         "(G) General:......... (0: G) \ n" +
         "(Default):........ (0) (default = 'G') \ n" +
         "(N) Number:......... (0: N) \ n" +
         "(P) Percent:......... (1: P) \ n" +
         "(R) Round-trip:....... (1: R) \ n" +
         "(X) Hexadecimal:....... (0: X) \ n",
         100, 3.14107);
     Console: WriteLine (Str);
    
     Str = String:: Format (3.14107->: (0 :#,#.##;}", 3.14107) / / 3.14
     Console: WriteLine (Str);
     Str = String:: Format ( "3555-> (0 :#,#.##;}", 3,555); / / 3.56
     Console: WriteLine (Str);
     Str = String:: Format ( "100 ->: (0,5:00 ###}", 100); / / 00100
     Console: WriteLine (Str);

The format is broken down as follows: (index [alignment] [: formatString])
You will find all descriptors format in the MSDN documentation.

VI. Conclusion

We'll have to adopt the solution that best suits

Comments
Add New Search
Write comment
Name:
Email:
 
Website:
Title:
UBBCode:
[b] [i] [u] [url] [quote] [code] [img] 
 
 
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
 
Please input the anti-spam code that you can read in the image.

3.22 Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

 
< Prev   Next >
School Joomla Templates and Joomla Tutorials