sprintf, how much money do you know?

Source: Internet
Author: User
Tags 04x comparison table

Selected "CSDN Community e-magazine--c/c++ magazine"
Http://emag.csdn.net January 2005 Issue 1-93-
Author: steedhorse (Morningstar)
printf is probably the second function that many program apes come into contact with when they start learning C (I guess the first one is main). Said
Get up. Nature is an old friend, but do you know much about this old friend? You know a lot about sprintf, the twin brother of it.
It? The power of sprintf is rarely disappointing when you construct various types of data into strings.
Since sprintf is almost identical to printf in the way it is used, it is only printed in a different destination than it is printed into a string.
The latter is output directly on the command line. This also causes sprintf to be much more practical than printf. So this article emphatically introduces sprintf. Sometimes
Also interspersed with the use of PRITNF.
sprintf is a variable function. Definitions such as the following:
int sprintf (char *buffer, const char *format [, argument] ...);
In addition to the first two parameter types, the following can be arbitrarily multiple parameters.

and the essence of it. Obviously in the second parameter:
The formatted string.


Both printf and sprintf use a formatted string to specify the format of the string. Use some
format specifiers (formatted specifications) that begin with "%" inside the format string to occupy a location. The corresponding variable is provided in the list of variables in the back, and finally the
function replaces that specifier with a variable of the corresponding position, producing a string that the caller wants.
Format numeric string
sprintf One of the most common applications is to print integers into strings, so SPRITNF can replace
Itoa in most cases. such as:
//The integer 123 is printed into a string stored in S.
sprintf (S, "%d", 123);//produces "123"
to specify width, insufficient left fill space:
sprintf (S, "%8d%8d", 123, 4567);//generated: "123 4567"
can also be left-justified:
sprintf (S, "%-8d%8d", 123, 4567),//Generate: "123 4567"
is also capable of printing in accordance with 16:
sprintf (S, "%8x", 4567);//lowercase 16-binary, Width is 8 positions, right-aligned
sprintf (S, "%-8x", 4568);//Uppercase 16-binary. Width is 8 positions, left-justified

In this way, an integer of 16 binary strings is very easy to get, but we are printing 16 binary content. Usually want a
To the left to fill 0 of the equal width of the format, then how to do it? It is very simple to add a 0 to the front of the number that represents the width.
sprintf (S, "%08x", 4567); Produce: "000011d7"
The above 10-binary printing with "%d" is also able to use the same way as the left 0.
Note the problem with a symbolic extension: for example, if we want to print short integers (1) of memory 16 into the tab
form, on the Win32 platform, a short type takes up 2 bytes, so we naturally want to use 4 16 binary numbers to hit
Print it:
Short si =-1;
sprintf (S, "%04x", si);
"FFFFFFFF", what's going on? Since SPRITNF is a variable function, in addition to the previous two parameters, the following
The parameters are not type-safe, and there is no way for the function to know that the first function call is a stack
is a 4-byte integer or a 2-byte short integer that is pressed in. So a unified 4-byte processing method is taken.
A symbol extension is made when the reference stack is pushed. Expands into a 32-bit integer-1, 4 positions are not enough to print, the 32-bit integer
-1 of the 8-bit 16 binaries are printed out.

Suppose you want to see the true nature of SI, then you should let the compiler do 0 extensions instead of
Symbol extension (extended binary left 0 instead of fill sign bit):
sprintf (S, "%04x", (unsigned short) SI);
will be able to.

Or:
unsigned short si =-1;
sprintf (S, "%04x", si);
sprintf and printf also have the ability to print integer strings in 8 binary, using "%o". Note that 8 binary and 16 binary are not hit
Printed negative numbers are unsigned, which is actually the direct 16-or 8-binary representation of the internal code of the variable.
Control floating-point printing format
The printing and formatting control of floating-point numbers is one of the most frequently used functions of sprintf. Floating-point numbers use the format character "%f" control, which is guaranteed by default
Leave 6 digits after the decimal point, for example:
sprintf (S, "%f", 3.1415926); Generate "3.141593"
But sometimes we want to control the width and scale of the print, then we should use: "%M.NF" format, where M-table
Shows the width of the print, and n indicates the number of digits after the decimal point. Example:
sprintf (S, "%10.3f", 3.1415626); Generated: "3.142"
sprintf (S, "%-10.3f", 3.1415626); Generated: "3.142"
sprintf (S, "%.3f", 3.1415626); The total width is not specified. Generated: "3.142"
Pay attention to a question, you guess.
int i = 100;
sprintf (S, "%.2f", I);
What's going to happen? "100.00"? Is that right? Try it yourself, and try this one at the same time:
sprintf (S, "%.2f", (double) i);
The first one to be typed is definitely not the right result, the same reason as mentioned earlier. The caller does not know that I
The corresponding format control is a "%f". The function itself does not know that it is an integer that was pressed into the stack when the function was executed.
So the wretched 4 bytes of the integer I are without any explanation forced to be interpreted as floating-point number format. It's all messed up.
Just suppose someone is interested in using a floating-point code that is manually encoded. Then you can use this method to test your hand
Are the results of the work arrangement correct?
Character/ascii Code comparison
We know. Char is also a common type of scalable in the C + + language, with short, in addition to the word length,
Int,long These types have no essential difference, they are just used to represent characters and strings. (Maybe it was time to
This type is called "byte" and is now able to use byte or short to set char through a TypeDef, depending on the actual situation.
This is more appropriate.)
So. Using "%d" or "%x" to print a character, it is possible to derive its 10 binary or 16-in ASCII code;
To print an integer using "%c", you will be able to see its corresponding ASCII character. The following section puts all the visible characters
The ASCII Code Comparison table is printed on the screen (using printf, note that "#" and "%x" when combined with the initiative to add "0X" to the 16 number of
Prefix):
for (int i = +; i < 127; i++) {
printf ("[%c]:%3d 0x% #04X/n", I, I, I);
}
Connection string
In the sprintf format control string, since it is possible to insert a variety of things and finally "string" them, it is natural to be able to connect
strings, which in many cases can be substituted for strcat, but sprintf can concatenate multiple strings at once (nature can also
Insert something else between them, in short, very flexible.

Example:
char* who = "I";
char* whom = "CSDN";
sprintf (S, "%s love%s.", who, whom); Produce: "I love CSDN." "
Strcat can only concatenate strings (a character array ending with '/0 ') or a character buffer. null-terminated-string).
But sometimes we have two-segment character buffers, and they don't end with '/0 '.

For example, many of the characters returned from a third-party library function
Group, a stream of characters read in from hardware or network transmissions, which may not necessarily have a corresponding '/0 ' after each sequence of characters
Tail.

Assuming a direct connection, either sprintf or Strcat will definitely lead to illegal memory operations. Strncat also requires at least the first
One of the parameters is a null-terminated-string. What should we do then? We will naturally recall the previous introduction to printing integers and floating-point numbers
Can specify the width, the string is the same. Example:
Char a1[] = {' A ', ' B ', ' C ', ' D ', ' E ', ' F ', ' G '};
Char a2[] = {' H ', ' I ', ' J ', ' K ', ' L ', ' M ', ' N '};
Assume:
sprintf (S, "%s%s", a1, A2); Don ' t do that!
There's going to be a problem.

Can you change it to:
sprintf (S, "%7s%7s", a1, A2);
It's not good to go anywhere. The correct one should be:
sprintf (S, "%.7s%.7s", a1, A2);//generated: "ABCDEFGHIJKLMN"
This can be analogous to the "%m.nf" of the print floating-point number, in "%m.ns", where M is the occupied width (empty when the string length is insufficient)
The actual width of the grid is printed). n represents the maximum number of characters to be taken from the corresponding string. Usually in the printed word
When the string is no big use, or the number of points after the n used more. Naturally, you can only take part of the characters before and after:
sprintf (S, "%.6s%.5s", a1, A2);//generated: "ABCDEFHIJKL"
In many cases. We might also want the numbers in these format controls to specify length information to be dynamic, not
Statically specified, because many times the program will be executed until it is clear that a few characters in the character array need to be taken. Such a
The dynamic width/precision setting is also taken into account in the implementation of sprintf, and sprintf uses "*" to occupy a
The position of the constant number of the specified width or precision, and the actual width or precision can be
Sample is provided, the above example can be turned into:
sprintf (S, "%.*s%.*s", 7, A1, 7, A2);
Or:
sprintf (S, "%.*s%.*s", sizeof (A1), A1, sizeof (A2), a2);
In fact, the previously described print characters, integers, floating-point numbers, and so on can dynamically specify those constant values, for example:
sprintf (S, "%-*d", 4, ' A '); Generate "65"
sprintf (S, "% #0 *x", 8, 128); Produce "0X000080". "#" generates 0X
sprintf (S, "%*.*f", 10, 2, 3.1415926); Generate "3.14"
Print address information
Sometimes when you debug a program, we may want to see the address of some variable or member. Since the address or pointer is just a 32-bit number, you can print them out using the "%u" that prints the unsigned integer:
sprintf (S, "%u", &i);
Just usually people prefer to use 16 binary instead of 10 to display an address:
sprintf (S, "%08x", &i);
However. These are indirect methods, and for address printing, SPRINTF provides a dedicated "%p":
sprintf (S, "%p", &i);
I think it's actually equivalent to:
sprintf (S, "%0*x", 2 * sizeof (void *), &i);
Take advantage of the return value of sprintf
Few people notice the return value of the printf/sprintf function, but sometimes it is practical. SPRITNF returns the function call
The number of characters that are finally printed to the character buffer. That is, you do not need to call again once the Sprinf call is finished.
Strlen already knows the length of the resulting string. Such as:
int len = sprintf (S, "%d", I);
For a positive integer, Len is equal to the number of 10 decimal digits of the integer i.
The following is a complete sample that produces a random number between 10 [0, 100) and prints them into a character array s,
separated by commas.


#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main () {
Srand (Time (0));
Char s[64];
int offset = 0;
for (int i = 0; i < i++) {
Offset + = sprintf (s + offset, "%d,", rand ()% 100);
}
S[OFFSET-1] = '/n ';//replace the last comma with a newline character.
printf (s);
return 0;
}
Imagine that when you take a record out of a database and then want to connect their fields to a single word in a certain rule
Character string. will be able to use such a method. Theoretically speaking. He should be more efficient than the constant strcat. Because strcat each call
It is necessary to first find the last position of the '/0 ', and in the example given above. Each time we use the sprintf return value to
A place to write it down directly.
Frequently asked questions about using sprintf
sprintf is a variable function that often has problems when used. And just a problem is usually a memory interview that can cause a program to crash.
Wrong, but fortunately by the misuse of sprintf caused by the problem despite serious, but very easy to find out, is nothing more than a few cases, through
Often use the eyes to see the wrong code more than a few eyes to see it.


??

Buffer overflow
The length of the first parameter is too short to say, give a bigger place. Of course, it could be the question of the latter.
, it is advisable to be careful when printing a string. Try to specify the maximum number of characters using the form "%.NS".
?? Forget the first number of references
Low-level can not be any more low-level problems, with printf used too accustomed. I often make it.

:。


?

? Change the corresponding problem
Generally forget to provide a corresponding format of the variable participation, resulting in the subsequent participation of all dislocation, check it.

Especially
It is the corresponding "*" of those parameters. Is it all available? Do not put an integer corresponding to a "%s", the compiler will think you
Bullying her too far (compiler is the mother of obj and EXE, should be a female,:P).
Strftime
SPRNITF also has a good cousin: Strftime, dedicated to formatting the time string, the use of her cousin very much like, also
is a large heap of format controls. Just after all, little roomed cautious. She also wants the caller to specify the maximum length of the buffer, which may be
To be able to shirk responsibility in the event of a malfunction.

Here's a sample example:
time_t t = time (0);
A string that produces a "yyyy-mm-dd hh:mm:ss" format.
Char s[32];
Strftime (S, sizeof (s), "%y-%m-%d%h:%m:%s", LocalTime (&t));
Sprintf can also find his bosom friend in MFC: Cstring::format. Strftime in MFC naturally also has her colleagues:
Ctime::format, the pair has been sponsored from object-oriented, and the code used to write it is more elegant.
Postscript
All of these features described in this article are very easy to find on MSDN, and I'm only using my own experience.
Combine some examples to put some frequently used ones. Practical. And probably a little bit about how many people have just started learning how to use it. Hope Big
Do not laugh at home, also hope that everyone criticize correct.
Some people think that such a function with a variable can cause various problems, so it is not advocated. But I still resist, I often don't
Its mighty Temptations. has been used in the actual work. Indeed, C#.net has supported variable parameters from the outset and has just published
Soon Java5.0 also supports variable parameters.
Thank you Ericzhangali (there is also a space) to mark a complete detailed draft, very correct little mistake. And put forward the suggestion.
Also thank Laomai (old) to read the entire manuscript and provide some suggestions for adding content.

sprintf, how much money do you know?

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.