Selected from "9CBS community e-magazine --C / C magazine" http://emag.9cbs.net January 2005, a total of --93-- author: steedhorse (Morningstar) printf may be the start of many programmers to learn The second function that came into contact with the C language (I guess the first is main), saying, naturally the old friend, but have you learned how much to this old friend? Do you know how much your twins brothers sprintf? When constructing various types of data into a string, the powerful feature of Sprintf rarely disappoints you. Since Sprintf is almost the same as the Printf, only the destination of print is different, the former prints into the string, the latter, then output on the command line. This also causes sprintf to be much useful than Printf. So this paper focuses on Sprintf, sometimes inserting with PRITNF. Sprintf is a variable-gate function, defined as follows: int sprintf (char * buffer, const char * format [, argument] ...); In addition to the first two parameter types, you can pick up any multiple parameters. And its essence, obviously in the second parameter: format strings. Both PRINTF and SPRINTF use formatted strings to specify the format of the string, and use some format spectrial specifence (Format Specifications) at the beginning of the format string to provide corresponding variables in the backward parameters of the rear. The final function will replace the specifier in the variable of the corresponding position, generate a buffer you want. One of the most common applications that format digital string sprintf is to print integers into the string, so spritnf can replace ITOA in most cases. If you print an integer 123 into a string saved in S. Sprintf (s, "% d", 123); // Generate "123" to specify the width, insufficient left resilience: Sprintf (S, "% 8D% 8D", 123, 4567); // Generate: "123 4567 "Of course, you can also align: Sprintf (S,"% -8d% 8D ", 123, 4567); // Generate:" 123 4567 "can also be printed in 16 credits: Sprintf (s,"% 8x ", 4567); / / lowercase 16 yuan, the width accounts for 8 positions, right aligned Sprintf (s, "% -8x", 4568); // uppercase 16-based, width accounts for 8 positions, left alignment
In this way, an integer's 16-enrich string is easy, but when we print 16 credit content, we usually want to have an equivalent format of the left to supplement 0. What should I do? Very simple, add 0 in front of the number indicating the width. Sprintf (s, "% 08x", 4567); // Generate: "000011D7" 10-based printing in "% D" is also used to use this way to supplement 0. Here, you should pay attention to a symbol extension problem: For example, if we want to print a short integer (short) -1 memory 16 credit representation, on the Win32 platform, a short type occupies 2 bytes, so we naturally hope to use 4 A 16-way number to print it: short si = -1; Sprintf (s, "% 04x", si); generate "ffffffffff", what is going on? Because spritnf is a variable-gate function, in addition to the two parameters, the back parameters are not type security, and the function can not know how only one "% X" can know when the first function call before the parameter stack is pressed. In the end, it is a 4-byte integer or a short integer of 2 bytes. Therefore, the unified 4-byte processing method is taken, causing the parameter stack to make a symbol extension, expanded to 32-bit integers -1, printing 4 positions are not enough, print 32-bit integers -1 8-bit bits. If you want to see the original face of Si, you should let the compiler do 0 expansions rather than symbol extensions (扩 二 二 左 0 0): Sprintf (S, "% 04x", (unsigned short) Si ); Or: unsigned short si = -1; sprintf (s, "% 04x", si); sprintf and printf can also press 8-based printing a nutrient string, using "% O". Note that 8 binders and 16 are not printing negative numbers, which are not symbol, which is actually the direct 16-coded or 8 binary representation of the internal encoding of the variable. Controlling the print and format control of floating point print format floating point number is another common function of sprintf, floating point number uses format "% F" control, the default retains 6 digits after the decimal point, such as: Sprintf (s, "% f" , 3.1415926); // Generate "3.141593" but sometimes we want yourself to control the width of the print and the decimal number, then use: "% m.nf" format, where m represents the width of the print, n represents the decimal point Bit number.
For example: Sprintf (S, "% 10.3F", 3.1415626); // Generate: "3.142" Sprintf (S, "%-10.3f", 3.1415626); // Generate: "3.142" Sprintf (s, "%. 3F ", 3.1415626); // Do not specify the total width, generate:" 3.142 "pay attention to a problem, you guess I = 100; Sprintf (s,"% .2f ", i); what will play? "100.00"? right? I will try it yourself, try the following: Sprintf (s, "% .2f", (double) i); the first one is definitely not the correct result, the reason is the same as mentioned above, parameters When the stack is stack, the caller does not know that the format control with I is a "% f". When the function execution function itself doesn't know that the integer is being pressed into the stack, the four bytes of poor storage integer i are unsolicited as a floating point number format, the whole chaos. However, if someone is interested in using a floating point number, you can use this method to verify that your hand-arranged results are correct. Character / ASCII code controls We know that in the C / C language, Char is also a normal Scalable type, except for the word length, it is not essentially different from Short, int, long, but is used to it. To represent characters and strings. (Perhaps this type is called "byte", and then it can now use Byte or short to define the CHAR through TypeDef according to the actual situation, so more appropriately), using "% D" or "% x" printing A character can derive its 10 credit or 16-based ASCII code; in turn, use "% C" to print an integer, you can see the ASCII characters it corresponds to. The following block prints all visible characters' ASCII code comparison table to the screen (here the Printf, pay attention to "#" and "% X" is used to add "0X" prefix): for (int i = 32; I <127; i ) {Printf ("[% C]:% 3D 0x% # 04x / n", i, i);} Connection string Sprintf's format control string can be inserted into various things And eventually "connect into a string", naturally it can connect to the string, so that many occasions can be replaced in Strcat, but the sprintf can connect multiple strings at a time (naturally insert other content in them in them, in short, Very flexible). For example: char * WHO = "i"; char * whom = "9cbs"; sprintf (s, "% s love% s.", WHO, WHOM); // generation: "i love 9cbs." Strcat can only connect String (a character array at the end of '/ 0' or Null-Terminated-string), but sometimes we have two character buffers, they are not ending with '/ 0'. For example, many characters from the third-party library function, read from hardware or network transfers, they do not have a corresponding '/ 0' after each sequence of characters.
If you connect directly, no matter whether sprintf or Strcat will definitely lead to illegal memory operation, and Strncat requires at least the first parameter is a null-terminated-string, what should I do? We naturally think of the previous introduction to print integers and floating point numbers, you can specify the width, the string is the same. For example: char A1 [] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; char A2 [] = {'h', 'I' , 'J', 'K', 'L', 'M', 'N'}; if: Sprintf (S, "% S% S", A1, A2); // Don't do this! Ten Eight nine wants to have problems. Whether it can be changed: Sprintf (S, "% 7S% 7S", A1, A2); not yet, correct: sprintf (s, "% .7777", A1, A2) ; // Generate: "Abcdefghijklmn" This can be classified than the "% m.nf" of the printed floating point, in "% m.ns", M represents the occupation width (the string length is insufficient, and the space is exceeded, according to the actual width Print), N represents the number of characters you take from the corresponding string. Usually m is not very large when the string is printed, or there is more than the nodes.
Natural, you can use only some characters before you: Sprintf (S, "%. 6S% .5s", A1, A2); // Generate: "Abcdefhijkl" In many cases, we may also want these format controls. The number of the specified length information is dynamic, not static specified, because many times, the program will be clear when the program needs to take several characters in the character array, this dynamic width / precision setting function in Sprintf The implementation is also taken into account, and the sprintf uses "*" to occupy a position where a constant number of a specified width or accuracy is, and the actual width or accuracy can be provided as other than other variables, Thus, the above example can becomes: Sprintf (S, "%. * S%. * S", 7, A1, 7, A2); or: Sprintf (s, "%. * S%. * S", SizeOf (A1), A1, SIZEOF (A2), A2); In fact, the printed characters, integers, floating point numbers, etc., which are described earlier, can dynamically specify those constant values, such as sprintf (s, "% - * d", 4, 'a'); // Generate "65" Sprintf (S, "% # 0 * x", 8, 128); // Generate "0x000080", "#" generates 0xsPrintf (s, "% *. * f ", 10, 2, 3.1415926); // Generate" 3.14 "print address information Sometimes when we want to view some variables or members of the member, because the address or pointer is not a 32-bit number, you are complete You can print them out using "% u" that print unsigned integers: Sprintf (s, "% u", & i); how often people still like to use 16-based rather than 10 envelopes: Sprintf (s , "% 08X", & i); however, these are indirect methods, for address printing, Sprintf provides special "% P": sprintf (s, "% p", & i); I think it actually Equivalent to: sprintf (s, "% 0 * x", 2 * sizeof (void *), & i); less people with Sprintf pay less attention to the return value of the PrintF / Sprintf function, but sometimes it is useful, Spritnf returns the number of characters in this function call finally printed into the character buffer. That is to say, every time the Sprinf call is over, you have no need to call a Strlen that has already known the length of the result string. Such as: int Len = Sprintf (s, "% d", i); for positive integers, LEN is equal to the 10-en-bits of integer i. The following is a complete example, generates a random number between [0, 100), and print them into a character array S, separated by a comma.
#include