Write a CSTRING class in a STL
From: Computer World
STL English is Standard Template Library, which is also the C standard template library we often say. The standard library was officially incorporated into the C standard in 1998 and brought the gospel to the C programmers around the world. What is most exciting should be its cross-platform, so that you can use the program written by standard C on the operating system of Window, UNIX, Linux without modification. (Of course there is a C compiler).
Now the compiler is different from the standard C support, it is still very good. The G of the VC, BC, Linux / UNIX platform of the Windows platform is a first-class compiler, support STL. And STL is active, you can expand, avoid these miniatures.
Speaking of STL first thing to say, of course, the string handling class std :: string, this may be a programmer to use the most class, it is very powerful, and it is very convenient to use. But it is a bit inconvenient to use the programmaker who is accustomed to use VC's CString. Fortunately, this inconvenience can be easily solved. The method is to package the standard string class std :: string to generate a class similar to CString, I named it xstring.
Below, you can talk from the Format function, which may be mostly used:
This function is a variable gate function, and the various functions of the parameters are as follows:
Int format (const char * pstrformat, ...)
Where pstrformat is a format string, three points represent all parameters. Each format in the format must correspond to it, otherwise the execution of the function will appear unexpected results; Of course too many parameters will be ignored. Format is divided into simple characters and conversion specification characters. The specific format specification has the following format:
% [Flags] [width] [.precision] [{H | L | i64 | L}] TYPE
Flags is a logo character, output alignment, tail zero, numerical symbol, number of credits (eight or sixteen)
Width is a width speculator, filling a number of spaces or 0
Precision is a precision speculatory, a maximum number of print characters, for an integer value, for a minimum number of numbers
H short integer output
I long integer output
I64 is 64-bit integer output
If you are not clear about the format, please refer to the format information about Printf.
Treatment for non-parameters is also very special, to use the following functions
First declare a variable va_list arglist;
VA_Start (arglist, pstrformat);
INT CNT = vSprintf (buff, pstrformat, arglist);
VA_END (arglist);
This saves the formatted results in the buff string.
Then the most important thing is to calculate how much this buff is, if there is memory waste, it is not a task, so it is necessary to dynamically calculate according to the format, then dynamically open the memory space. Use a loop to read each character in the format string separately. First initialize a length variable nmaxlen = 0;
For (const char * p = pstrformat; * p! = '0'; p )
If the read is not '%' or '%%', the length is plus one.
IF (* p! = '%' || * ( p) == '%')
{
NMAXLEN = 1;
CONTINUE;
}
If the previous character is '%', read the format, if it is '#', the length is plus 2, to the '0x' reserved space; if it is '*', read the integer to be specified The width; other characters such as ' ', '-', '', '0' are mainly filled, ignored the length. For (; * p! = '0'; p )
{
IF (* p == '#')
NMAXLEN = 2; // Handling '0x'
ELSE IF (* p == '*')
NWIDTH = VA_ARG (arglist, int); //, such as: '% 5f' 5
Else if (* p == '-' || * p == ' ' || * p == '0' || * p == ')
; // ignore the symbol
ELSE / / is not a logo character to exit the loop
Break;
}
If the next character is '.', Ignore the back of the following characters, if it is '*', it is also necessary to read the subsequent width to calculate the accuracy.
IF (* p == '*')
{
NPRECISION = VA_ARG (Arglist, int);
P ;
}
Else
{
NPRECISION = ATOI (P);
For (; * p! = '0' && isdigit (* p); p )
;
}
Next, the character is ignored if 'h', 'L', 'I', 'F', 'N', etc., the calculation length is ignored.
If the reading character is 'c', 'c', the length plus 2 (considering the width character); if the 's', 's' is read, the width of the string given in the parameter is calculated.
Switch (* p)
{
Case 'C':
Case 'C':
NITEMLEN = 2;
VA_ARG (Arglist, char);
Break;
Case 's': // String
Case 's':
NITEMLEN = Strlen (Va_arg (arglist, const char *);
NITEMLEN = ((1)> (NITEMLEN))? (1): (NITEMLEN); // If it is an empty string, use 1 to save '0'
Break;
}
If the read characters are 'D', 'I', 'u', 'X', 'O', 'E', 'F', 'g', 'g', etc., the length plus the corresponding value. The length of the type, of course, it is best to use the SIZEOF calculation to make better gravesting capabilities.
Case 'd':
Case 'I':
Case 'u':
Case 'x':
Case 'x':
Case 'o':
VA_ARG (Arglist, int);
NITEMLEN = 32;
At the end of the FOR cycle, there is, of course, don't forget to take the length of NMAXLEN = Nitemlen; when the cycle ends, the calculation of the length is completed.
Call va_end (arglist) at the end of the FOR cycle;
Below you can open the right memory space to save your format string.
Char * ch = new char [nmaxlen 1];
There is a space to re-receive parameters.
VA_Start (arglist, pstrformat);
vSprintf (ch, pstrformat, arglist);
VA_END (arglist);
Finally don't forget to add space to std :: string, you can call the Append function directly:
this-> append (ch);
Then release your memory space
DELETE [] CH; other functions can be packaged with corresponding features in std :: string, and then write a Makeupper function below, which is also CString.
void makeupper ()
{
Std :: Transform (this-> begin (),
THIS-> End (), this-> begin (),
TouPper);
}
Is it easy, I hope this article can play a role in tiles, bringing you to use STL.
The above program codes can be used in VC and G . I used the XString class to replace all CString classes in the project written in MFC, making it easy to compile with G .