Sprintf function details

Source: Internet
Author: User
Tags 04x comparison table print format
Function:
Write formatted data into a string
Header file:
Stdio. h
Function prototype:
Int sprintf (char * buffer, const char * format, [argument]… );
Parameter List:
Buffer: Char pointer, pointing to the string address to be written.
Format: Char pointer. the pointer to the memory contains the format string.
[Argument]...: optional parameter, which can be any type of data.
Return Value: String Length (strlen)
Related functions:
Int sprintf_s (char * buffer, size_t sizeofbuffer, const char * format, [argument]...); int _ sprintf_s_l (char * buffer, size_t sizeofbuffer, const char * format, locale_t locale, [argument]...); int swprintf_s (wchar_t * buffer, size_t sizeofbuffer, const wchar_t * format, [argument]...); int _ swprintf_s_l (wchar_t * buffer, size_t sizeofbuffer, const wchar_t * format, locale_t locale, [argument]…); Template <size_t size> int sprintf_s (char (& buffer) [size], const char * format, [argument]...); // only exist in C ++ template <size_t size> int swprintf_s (wchar_t (& buffer) [size], const wchar_t * format, [argument]...); // only available in C ++

The string formatting command is mainly used to write formatted data into a string. Sprintf is a variable parameter function, which often causes problems when used, and as long as there is a problem, it is usually the memory access error that can cause the program to crash.Mistake, but fortunately, the problems caused by the misuse of sprintf are very serious, but it is easy to find out. It is nothing more than a few situations. Usually I can see the wrong code with my eyes.

Parameter description and Application Example

The sprintf format specifications are as follows. [] Is optional.
% [Specified parameter] [identifier] [width] [. Precision] indicator
If you want to output '%' itself, handle it like this '%.
1. process the character direction. When the negative sign is used, it indicates processing from the back to the front.
2. Fill in the blanks. If the value is 0, it indicates that the space is filled with 0; if the space is an internal value, it indicates that the space is placed.
3. Total character width. Minimum width.
4. accuracy. The number of digits after the decimal point.
Conversion character
 
% Indicates the percentage, which is not converted.
The % C integer is converted to the corresponding ASCII character.
% D integer to decimal place.
% F times the precision number to a floating point number.
% O integer to octal.
% S integer to string.
% X integer to lowercase hexadecimal.
% X integer to uppercase hexadecimal.

$ Money = 123.1 $ formatted = sprintf ("% 06.2f", $ money); // The variable $ formatted value is "123.10" $ formatted = sprintf ("% 08.2f ", $ money); // The variable $ formatted is "00123.10" $ formatted = sprintf ("%-08.2f", $ money ); // The variable $ formatted is "123.1000" $ formatted = sprintf ("%. 2f % ", 0.95*100); // format as a percentage

Explanation:

Start character
0 indicates the "fill in character". If the length is insufficient, fill it with 0.
8. Total length after formatting
2f decimal point length, that is, 2 digits
The value of row 3rd is 00123.10. Explanation:
Because 2f is (2 bits) + decimal point (1 bits) + first 123 (3 bits) = 6 bits, the total length is 8 bits, therefore, the preceding [fill-in character] 0 is used, that is, 00123.10
The value of row 4th is 123.1000. Explanation:
-It indicates a reverse operation. Then, the blank character 0 is added to the end.
When constructing various types of data into strings, the powerful features of sprintf seldom disappoint you. Since sprintf and printf have almost the same usage, but the printing destination is different, the former is printed into the string, and the latter is directly output on the command line. This also makes sprintf much more useful than printf.
Sprintf is a variable parameter function, which is defined as follows:
Int sprintf (char * buffer, const char * Format [, argument]...);
In addition to the fixed types of the first two parameters, you can take over multiple parameters later. But its essence is obviously in the second parameter:
Format the string.
Both printf and sprintf use formatted strings to specify the string format. Some format specifiers (format specifications) starting with "%" are used inside the format string to occupy a position, the variable is provided in the variable parameter list, and the function will replace the specifier with the variable at the corresponding position to generate the string that the caller wants.
One of the most common applications of formatting a numeric string sprintf is to print an integer to a string. Therefore, sprintf can replace ITOA in most cases.

For example:
// Print the integer 123 into a string and save it in S.
Sprintf (S, "% d", 123); // generate "123"
You can specify the width. If the width is insufficient, spaces are filled on the left:
Sprintf (S, "% 8d % 8d", 123,456 7); // generate: "123 4567"
Of course, you can also align left:
Sprintf (S, "%-8d % 8d", 123,456 7); // generate: "123 4567"
You can also print the data in hexadecimal format:
Sprintf (S, "% 8x", 4567); // lowercase hexadecimal notation, with 8 width positions and right alignment
Sprintf (S, "%-8x", 4568); // in hexadecimal notation, the width occupies 8 positions and is left aligned.
In this way, the hexadecimal string of an integer is easy to obtain, but when printing the hexadecimal content, we usually want an equal-width format with 0 on the left, what should we do? Simply add 0 to the number that represents the width.
Sprintf (S, "% 08x", 4567); // generate: "201711d7"
You can also use this left-side 0 Complement Method to print the 10-in-hexadecimal format with "% d" above.
Pay attention to a symbol extension problem: for example, if we want to print a short INTEGER (short)-1 memory hexadecimal representation, on the Win32 platform, A short type occupies 2 bytes, So we naturally want to print it with 4 hexadecimal numbers:
Short Si =-1;
Sprintf (S, "% 04x", Si );
Why is "ffffffff" generated? Because spritnf is a Variable Parameter Function, except the first two parameters, the following parameters are not of type security, there is no way for a function to know whether a 4-byte integer or a 2-byte short integer is pressed in the parameter stack before the function call through a "% x "., therefore, a 4-byte processing method is adopted, which leads to the symbol extension during parameter pressure stack, which is a 32-bit integer-1. When printing, the four locations are insufficient, print out the 8-bit 16 hexadecimal values of 32-bit integer-1.
If you want to see the original form of Si, you should let the compiler do 0 extension instead of symbol extension (during expansion, the left side of the binary complement 0 instead of the sign bit ):
Sprintf (S, "% 04x", (unsigned short) Si );
You can. Or:
Unsigned short Si =-1;
Sprintf (S, "% 04x", Si );
Sprintf and printf can also print integer strings in octal, using "% O ". Note that both the octal and hexadecimal formats do not print negative numbers. They are all unsigned. In fact, they are the direct hexadecimal or octal representation of the variable's internal code.
Control floating point print format
The printing and format control of floating point numbers is another common function of sprintf. Floating Point Numbers are controlled by the format character "% F". By default, the six digits after the decimal point are retained, for example:
Sprintf (S, "% F", 3.1415926); // generate "3.141593"
But sometimes we want to control the print width and decimal places by ourselves, then we should use the format "% m/NF", where M represents the print width, N represents the number of digits after the decimal point. 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); // The total width is not specified, resulting in: "3.142"
Pay attention to one question, you guess
Int I = 100;
Sprintf (S, "%. 2f", I );
What will it do? 100.00 "? Right? Try it on your own and try the following:
Sprintf (S, "%. 2f", (double) I );
The first one is definitely not the correct result, because, as mentioned above, the caller does not know that the format controller corresponding to I is "% F" when the parameter is pressed ". When a function is executed, the function itself does not know that the number pushed to the stack in the current year is an integer, so the four bytes that saved the integer I were forcibly interpreted as a floating-point number. However, if someone is interested in manually encoding a floating point number, you can use this method to check whether the result of your manual arrangement is correct.
Character/ASCII code comparison
We know that in C/C ++, char is also a common scalable type. In addition to the word length, it has no essential difference with short, Int, and long, it is used to represent characters and strings. (Maybe this type was called "byte" in the past, and now we can use byte or short to define char through typedef according to the actual situation, which is more appropriate, print a character using "% d" or "% x" to obtain its 10-or 16-digit ASCII code. Conversely, print an integer using "% C" to see its ASCII characters. The following section describes the ASCII values of all visible characters.
The Code comparison table is printed on the screen (printf is used here. Note that "#" and "% x" are automatically prefixed with "0x" when used together ):
For (INT I = 32; I <127; I ++ ){
Printf ("[% C]: % 3d 0x % # 04x \ n", I, I );
}
Connection string
Since the sprintf format control string can insert various things and "connect them together", it can naturally connect strings, which can replace strcat in many occasions, but sprintf can connect multiple strings at a time (it can also insert other content in them at the same time, in short, it is very flexible ). For example:
Char * Who = "I ";
Char * Whom = "csdn ";
Sprintf (S, "% s love % S.", who, whom); // generate: "I love csdn ."
Strcat can only connect strings (an array of characters ending with ''or a character buffer, null-terminated-string), but sometimes we have two character buffers, they do not end. For example, for many character arrays returned from third-party library functions and the sequence streams read from hardware or network transmission, they may not end with a corresponding ''after each character sequence. If you connect directly, whether sprintf or strcat will certainly lead to illegal memory operations, and strncat also requires at least the first parameter to be null-terminated-string. What should we do? We naturally remember that the width can be specified when we first introduced printing integers and floating-point numbers, and the strings are 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 that!
In, something went wrong. Can it be changed:
Sprintf (S, "% 7 S % 7 s", a1, a2 );
It's not good where to go. The correct one should be:
Sprintf (S, "%. 7 S %. 7 s", a1, a2); // generate: "abcdefghijklmn"
This can be analogous to printing the "% m/NF" of the floating point number, at "% m. in "ns", "M" indicates the width occupied (when the string length is insufficient, fill in spaces. If the length exceeds the limit, print it according to the actual width). "N" indicates the maximum number of characters used from the corresponding string. Generally, M is useless when printing strings, but n is usually used after the dot. Naturally, you can only take part of the characters before and after:
Sprintf (S, "%. 6 S %. 5 s", a1, a2); // generate: "abcdefhijkl"
In many cases, we may also want the numbers in these format controllers to specify length information to be dynamic, rather than static, because many times, when the program is running, it will know exactly how many characters in the character array need to be taken. This dynamic width/precision setting function is also taken into account in the implementation of sprintf, sprintf uses "*" to occupy a position that originally requires a constant number with a specified width or accuracy. Similarly, the actual width or accuracy can be provided like other printed variables, so the preceding example can be changed:
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, and floating-point numbers described above can all dynamically specify the constant values, such:
Sprintf (S, "%-* D", 4, 'A'); // generate "65"
Sprintf (S, "% #0 * X", 8,128); // generate "0x000080", "#" generate 0x
Sprintf (S, "% *. * F", 10, 2, 3.1415926); // generate "3.14"
Print address information
Sometimes, when debugging a program, we may want to view the addresses of some variables or members. Because the addresses or pointers are only 32-bit numbers, you can print the unsigned integers "% u:
Sprintf (S, "% u", & I );
However, people usually prefer to use hexadecimal instead of hexadecimal to display an address:
Sprintf (S, "% 08x", & I );
However, these are indirect methods. For address printing, sprintf provides a special "% P ":
Sprintf (S, "% P", & I );
I think it is actually equivalent:
Sprintf (S, "% 0 * X", 2 * sizeof (void *), & I );
Use sprintf's Return Value
Few people pay attention to the return values of the printf/sprintf function, but sometimes it is useful. spritnf returns the number of characters that the function call finally prints to the character buffer. That is to say, after each sprinf call ends, you do not need to call strlen again to know the length of the result string. For example:
Int Len = sprintf (S, "% d", I );
For a positive integer, Len is equal to the 10-digit digits of the integer I.
The following is a complete example, which generates a random number between 10 [0,100) and prints them to a character array S,
Separated by commas.
# Include <stdio. h> # include <stdlib. h> # include <time. h> int main () {srand (time (0); char s [64]; int offset = 0; For (INT I = 0; I <10; I ++) {Offset + = sprintf (S + offset, "% d,", Rand () % 100);} s [offset-1] = '\ n '; // Replace the last comma with a line break. Printf (s); Return 0 ;}

Imagine that when you extract a record from the database and want to connect each of their fields into a string according to certain rules, you can use this method. Theoretically, it should be more efficient than the continuous strcat, because each call to strcat needs to first find the final location, and in the example given above, every time we use the sprintf return value to write down this position directly.
FAQ about using sprintf

Sprintf is a variable parameter function, which often causes problems when used, and as long as there is a problem, it is usually the memory access that can cause the program to crash.
Wrong, but fortunately, the problems caused by the misuse of sprintf are serious, but it is easy to find out, there are only a few situations
The common eyes can see the error code with a few more eyes.
Sprintf_s () is a secure version of sprintf (). You can specify the buffer length to avoid the Overflow Risk of sprintf. If you use the sprintf function in vs2008, the compiler will issue a warning: there is a risk to use sprintf. We recommend that you use sprintf_s. The Security version is prototype:
Int sprintf_s (char * buffer, size_t sizeofbuffer, const char * Format [, argument]...);
Buffer Overflow
The length of the first parameter is too short. If you don't want to say it, just give it a bigger one. Of course, it may also be the following parameter question.
It is recommended that you be careful when changing parameters. When printing a string, use the "%. Ns" format to specify the maximum number of characters.
The first parameter is missing.
Low-level users cannot have low-level problems. They are too familiar with printf. // It is common. :. (
An error occurred while changing the parameter.
Generally, you forget to provide variable parameters corresponding to a certain format character, which leads to misplacement of all subsequent parameters. Check the parameters. You
Are all parameters corresponding to "*" provided? Do not map an integer to "% s". The compiler will think that you
It's so bad (the compiler is the mother of OBJ and exe, it should be a female, P ).
Strftime
Sprnitf also has a good cousin: strftime, which is specially used to format the time string. Its usage is similar to that of her cousin.
It is a lot of format controllers, but after all, the girl's family is fine, and she also needs to specify the maximum length of the buffer, which may be
You can shirk responsibility when a problem occurs. Here is an example:
Time_t t = time (0 );
// Generate a string in the format of "YYYY-MM-DD hh: mm: SS.
Char s [32];
Strftime (S, sizeof (s), "% Y-% m-% d % H: % m: % s", localtime (& T ));
Sprintf can also find its Zhiyin: cstring: format in MFC, and strftime naturally has her same path in MFC:
Ctime: format, which is more elegant because of the sponsorship of the object-oriented code.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.