Sprintf and snprintf

Source: Internet
Author: User
Tags 04x

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. Its essence is obviously on the second parameter: Format String.
Both printf and sprintf use formatted strings to specify the string format. Some format specifiers starting with "%" (Format
Specifications) to occupy a location, provide the corresponding variables in the Variable Parameter List behind, and the final function will replace the specifier with the variables of the corresponding location, generate a caller wants
.
1. format the numeric string
One of the most common applications of sprintf is to print Integers to strings. Therefore, spritnf 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, and the function cannot simply use one

"% X" indicates whether the parameter pushed to the stack before the function call is a 4-byte integer or a 2-byte short integer, therefore, a 4-byte processing method is adopted, which causes the parameter to be written when the parameter is pressed to the stack.

Number is extended to 32-bit integer-1. When the four locations are not enough, the 8-bit 16 of 32-bit integer-1 is printed out. If you want to see the original form of Si, you should make the compilation
0 extension rather than symbol extension (the left side of the binary complement 0 rather than sign bit during extension ):

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.
2. Control the floating point printing 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 indicates the print width, N indicates 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 ". The function itself does not know when the function is executed.
When it was pushed into the stack, it was an integer. Therefore, the four bytes that saved the integer I were forcibly interpreted as a floating point format.
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. J
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. Only

However, it is used to represent characters and strings. (Maybe this type is called "Byte" in the past, and now we can use byte or short to put char according to the actual situation.
Defined by typedef, which is more appropriate)
Therefore, print a character using "% d" or "% x" to obtain its 10-or 16-digit ASCII code. In turn, print an integer using "% C" and you can see the corresponding
ASCII characters.


Int snprintf (char * restrict Buf, size_t N, const char * restrict format ,...);

Function Description: a maximum of N-1 characters can be copied from the source string to the target string, followed by 0. Therefore, if the target string is N, it will not overflow.

Function return value: If the value is successful, the length of the string to be written is returned. If an error occurs, a negative value is returned.

Result1 (recommended)

# Include <stdio. h>
# Include <stdlib. h>

Int main ()
{
Char STR [10] = {0 ,};
Snprintf (STR, sizeof (Str
)
("0123456789012345678 ");
Printf ("str = % s/n", STR );
Return 0;
}

Root]/root/lindatest
$./Test
Str= 012345678

Result2: (not recommended)

# Include <stdio. h>
# Include <stdlib. h>

Int main ()
{
Char STR [10] = {0 ,};
Snprintf (STR, 18, "0123456789012345678 ");
Printf ("str = % s/n", STR );
Return 0;
}

Root]/root/lindatest
$./Test
Str= 01234567890123456

Test the returned values of the snprintf function:

# Include <stdio. h>
# Include <stdlib. h>

Int main ()
{
Char str1 [10] = {0 ,};
Char str2 [10] = {0 ,};
Int ret1 = 0, ret2 = 0;
Ret1 = snprintf (str1, sizeof (str1), "% s", "ABC ");
Ret2 = snprintf (str2, 4, "% s", "aaabbbccc ");
Printf ("aaabbbccc length = % d/N", strlen ("aaabbbccc "));
Printf ("str1 = % s, ret1 = % d/N", str1, ret1 );
Printf ("str2 = % s, ret2 = % d/N", str2, ret2 );
Return 0;
}

[Root]/root/lindatest
$./Test
Aaabbbccc length = 9
Str1 = ABC, ret1 = 3
Str2 = aaa, ret2 = 9

Explanation size:

#include
# include
int main ()
{< br> char dst1 [10] = {0,}, dst2 [10] = {0 ,};
char src1 [10] = "AAA", src2 [15] = "aaabbbcccddd";
int size = sizeof (dst1 );
int ret1 = 0, ret2 = 0;
ret1 = snprintf (dst1, size, "str: % s", src1 );
ret2 = snprintf (dst2, size, "str: % s", src2);
printf ("sizeof (dst1) = % d, src1 = % s, /"str: % S/" = % S % s, dst1 = % s, ret1 = % d/N ", sizeof (dst1), src1," str :", src1, dst1, ret1);
printf ("sizeof (dst2) = % d, src2 = % s,/" str: % S/"= % S % s, dst2 = % s, ret2 = % d/N", sizeof (dst2), src2, "str:", src2, dst2, ret2);
return 0;
}< br> root]/root/lindatest
$. /test
sizeof (dst1) = 10, src1 = aaa, "str: % s" = STR: AAA, dst1 = STR: AAA, ret1 = 8
sizeof (dst2) = 10, src2 = aaabbbcccddd, "str: % s" = STR: aaabbbcccddd, dst2 = STR: aaab, ret2 = 17

In addition, the returned value of snprintf is the length of the string to be written, rather than the degree of actually written string. For example:
Char test [8];
Int ret = snprintf (test, 5, "1234567890 ");
Printf ("% d | % s/n", RET, test );

The running result is:
10 | 1234


Data prototype:
Int snprintf (char * STR, size_t size, const char * format ,...);

  Size is used to limit the number of bytes (including '/0' at the end) written to Str '). Because if the sprintf () function is successful, the number of bytes (number of characters) written to the sprintf () function is returned, and I always thought that the snprintf () function is also like this, that is, snprintf () the function does not return an integer greater than the size.   See the following manual:   The functions snprintf () and vsnprintf () do not write more
Than size bytes (including the trailing '/0'). If the output was
Truncated due to this limit then the return value is the number
Characters (not including the trailing '/0') which wowould have been
Written to the final string if enough space had been available. Thus,
A return value of size or more means that the output was truncated.

  If the output is truncated due to the size limit, the returned value is "if there is enough storage space
Ying

Number of characters that can be output (excluding '/0' at the end of the string) ". The value is equal to or greater than the size! That is to say, if the string that can be written is
"0123456789 abcdef"
A total of 16 bits, but the size limit is 10, so that the returned value of snprintf () will be 16

Instead
10
!   The above content also says that if the returned value is equal to or greater than the size, it indicates that the output string is truncated (truncated ).

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.