Boost Lexical

xiaoxiao2021-03-06  67

Transfer from: http://www.c-view.org/person/chong/approach2boost.htm#idahdsab

Introduction to Boost

What is BOOST? A set of open source, highly portable C libraries. Who is initiated? Working Group C Standard Board Working Group. Therefore, quality assurance is not afraid to encounter counterfeiting and shoddy products.

What is it?瞧:

Regular expressions can be comparable to the POSIX API and Perl language to handle regular expressions, but also support various character types (such as char, wchar_t, or even custom character types); multithreading, thinking about it for a long time Cross-platform multi-thread library; data structure "map", plus upcoming standard Hash_SET, Hash_MAP, Hash_MultiSet, hash_multimap, etc. In fact, such as SGI STL, has supported the above data structure), C supports the support of the data structure has been complete; python, is wrong, support for the Python language; intelligent pointer, good use with std :: auto_ptr, can eliminate memory leaks, efficiency and garbage collection mechanism GC on the same day More cyclic redundant CRC, easy to define a tuple TUPLE that returns multiple values ​​functions, can accommodate the ANY of different types, supplemented to all aspects of the standard library ... Still expand, some content is expected to enter C Standard library ...

Lexical_cast

This time we first pick a simple and practical Boost component to see what Boost can bring us convenience.

String → value

On the 9CBS Forum, I often see how to transform between string types and numerical types, and I have seen many different answers. Let's discuss the conversion from string types to numerical types.

How to convert a string "123" to int type integer 123? The answer is, use standard C library function atoi; if you want to convert to long type? Standard C library function atol; how to convert "123.12" into double type? Standard C library function ATOD; if you want to convert to long double type? Standard C library function atOLD; ......

Later, there were friends to start using the String class in the standard library, ask this how to convert it into a value? Some friends answer, please turn to const char *. I admire the responses' thinking of mathematicians: transforming unfamiliar issues into familiar issues. (I have had a joke, the good matter asked the mathematician: Do you know how to burn water? A: I know. Put the kettle full water, ignite the burning. Ask: If there is water in the kettle? A: Pour it first, Transforming to my familiar problem ...)

No, no, this is C's approach, not C . So what should C do? The function lexical_cast (need to introduce header file boost / lexical_cast.hpp) is undoubtedly easier to use the function lexical_cast provided by Boost Conversion Library. Such as:

#include

#include

int main ()

{

Using boost :: lexical_cast;

INT A = lexical_cast ("123"); double b = lexical_cast ("123.12");

Std :: cout << a << std :: endl

Std :: cout << B << std :: end1;

Return 0;

} A function is simply solved all problems.

Value → string

So what is the type of value to a string?

Use ITOA? No, there is no such function at all in standard C / C . Even if some compilers under the Windows platform provide this function [3], there is no transplantability, but only the int type (perhaps other functions can also solve the type of long, unsigned long), how is the floating point type? do? Of course, the way is still there, that is: Sprintf.

Char s [100];

Sprintf (s, "% f", 123.123456);

I don't know if you are in C.

What is the impression of the Scanf / Printf series, and I can't remember those of those whimged parameters, and if you write a wrong parameter, you will get an inexplicable output result. If you debug it, you can have to live (I hate the character array Space open 100, afraid too small; open 100000, always feel too wasteful, heart is suffocating, good at C standards for us

String such a string class). At this moment,

Lexical_cast is coming out.

#include

#include

#include

int main ()

{

Using std :: string;

Const Double D = 123.12;

String s = boost :: lexical_cast (d);

Std :: cout << S << std :: end1;

Return 0;

} As simple as the front.

abnormal

If the conversion fails, it will have an exception Bad_lexical_cast. This anomaly class is a subclass of standard anomaly BAD_CAST.

#include

#include

int main ()

{

Using std :: cout;

Using std :: end1;

INT I;

Try {

I = boost :: lexical_cast ("abcd");

}

Catch (boost :: bad_lexical_cast & e)

{

Cout << E.WHAT () << endl;

Return 1;

}

COUT << i << endl;

Return 0;

} Obviously "ABCD" does not convert to an int type value, throwing an exception, capturing information "Bad Lexical Cast: Source Type Value Could Not Be Interpreted as Target".

Precautions

Lexical_cast depends on the character stream std :: stringstream (automatically introduced first "SSTREAM> [4]), its principle is quite simple: read the source type into the character stream, and then write it to the target type. For example INT D = Boost :: Lexical_cast ("123"); it is equivalent to

INT D;

Std :: stringstream s;

S << "123";

S >> D; since it is using a character stream, of course, there are some problems that follow, it needs to be specifically pointed out.

[5].

Since the localization of Visual C 6 implements problems, if you use non-default Locale, you may be inexplicably throwing an exception. Of course, in general, we don't need to change the default Locale, so the problem is not very big. The input data must be "complete" to convert, otherwise the Bad_lexical_cast exception is thrown. For example I = boost :: lexical_cast ("123.123"); // this Will Throw

Will throw an exception. Because "123.123" can only "partially" to 123, it cannot be "complete" to 123.123. The accuracy problem of floating point numbers.

Std: string s = boost :: lexical_cast (123.1234567);

The result of the above statement is "123.1234567", but in fact, we will only get "123.123", because the accuracy of Std :: StringStream is 6 (this is the "senior" Printf in the C language library. Tradition). This can be said to be a bug of Boost :: Lexical_cast. How to do it? Meeting of power, can do this: Open the header file , pay attention to the modification [6]: #include

// ...

Template

Target Lexical_cast (Source Arg) {

// ...

Target Result;

Interpreter.Precision (std :: numeric_limits :: digits10);

IF (! ("(interpreter << arg) ||

! (Interpreter >> Result) ||

! (Interpreter >> std :: ws) .eof ())

// ...

} You can get the correct result. Of course, there will be a little loss in theoretical efficiency, but it is almost negligible.

summary

We have experienced Boost :: Lexcial_cast. Of course, Lexical_cast is not limited to the conversion between string type and numerical type: can be converted from the type of StringStream input to the type and any type of StringStream input. This understanding, although it is rough, but after all, we have "walk into Boost", not just "approach". In the future, we can experience the moving of Boost yourself.

[1] If you have a DNS error in the Boost English website, http://64.226.201.52/.

[2] Please refer to the "Download Download and Installation" section in the Boost document. [3] Borland C Builder provides ITOA, while Microsoft Visual C provides a function of the same function, but the name is _itoa.

[4] Some standard library implementations that do not meet the standards, the character stream name is Strstream, in the header file . Standard specified Stringstream, in the header file .

[5] Please refer to the discussion of http://groups.yahoo.com/group/boost/message/15023.

[6] Thank you very much for Andrew Koenig and Bjarne Stroustrup two advice and help. The most beginning my thoughts are to specify the maximum accuracy, join the statement such as Interpreter.Precision (15), but worry about the problem of transplantability. Mr. Andrew Koenig gives a very clear explanation: You are quite correct that 15 is not portable across all floating-point implementations However, it is portable across all implementations that support IEEE floating-point arithmetic, which is most computers that are in. common use today. If you want to do better than that, you might consider using numeric_limits :: digits10, which is the number of significant base-10 digits that can be accurately represented in a double. (Chinese effect that, admittedly 15 is not transplantable to all floating point implementations, but for the implementation of IEEE floating point operations, it is indeed portable, and this is also used in most computers today. If you want to do better One point, you can consider using numeric_limits :: digits10, you can indicate the number of digits that Double can accurately express 10 envelopes.)

转载请注明原文地址:https://www.9cbs.com/read-89686.html

New Post(0)