Program use cases for the sprintf () function:
#include
#include
int main (void)
{
Char buffer[80];
sprintf (buffer, "an approximation of Pi is%f\n", M_PI);
puts (buffer);
return 0;
}
The role of sprintf is to output a formatted string to a destination string, while printf prints a formatted string to the screen.
The first parameter of the sprintf is the destination string, and if you do not specify this parameter, "the program will be shut down ..." when it is executed in an illegal operation.
Tips.
Because the C language does not check that the string is large enough for string manipulation, it is possible that the array may be out of bounds and cause the program to crash.
Even if it happens, the program is not wrong, do not use it, because the early evening error. So be sure to allocate enough space before calling sprintf to BUF. sprintf is a variable parameter function, defined as follows:
int sprintf (char *buffer, const char *format [, argument] ...);
In addition to the first two parameter types are fixed, any number of parameters can be followed. And its essence, obviously, is on the second argument: Formatting the string.
Both printf and sprintf use a formatted string to specify the format of the string, using some of the "%" inside the format string
form specifier (format specifications) to occupy a position, provide the corresponding variable in the argument list, and finally
The function replaces the descriptor with the variable in the corresponding position, producing a string that the caller wants.
To format a string of numbers
one of the most common applications of sprintf is to print integers to a string, so SPRITNF can replace itoa in most situations. Such as:
1> the integer 123 into a string stored in S.
sprintf (S, "%d", 123); Produce "123"
2> can specify width, insufficient left fill space:
sprintf (S, "%8d%8d", 123, 4567); Generated: "123 4567"
3> Of course can also be left-aligned:
sprintf (S, "%-8d%8d", 123, 4567); Generated: "123 4567"
4> can also be printed in 16:
sprintf (S, "%8x", 4567); lowercase 16, width to 8 positions, right aligned
sprintf (S, "%-8x", 4568); Uppercase 16, width to 8 positions, left-aligned
This way, an integer's 16 string is easy to get, but when we print the 16-in content, we usually want a
To the left 0 of the equal-width format, then how to do it. Simply put a 0 in front of the number that represents the width.
sprintf (S, "%08x", 4567); Produce: "000011d7"
The 10-in-print printing above with "%d" can also use this left complement of 0.
Notice the problem of a symbolic extension: for example, if we want to print a short integer (shorter)-1 memory 16 into the tab
form, on the Win32 platform, a short type occupies 2 bytes, so we naturally want to use 4 16 digits to hit
Print it:
Short si =-1;
sprintf (S, "%04x", si);
Produce "ffffffff", what's going on. Because SPRITNF is a variable parameter function, in addition to the preceding two parameters, the following
Parameters are not type-safe, and functions have no way of simply using a "%x" to know the parameters of the previous function call stack
is a 4-byte integer or a 2-byte short integer pressed in, so a uniform 4-byte approach is taken,
Cause the parameter stack when the symbolic extension, expanded into a 32-bit integer-1, printing when 4 position is not enough, the 32-bit integer
-1 of the 8-bit 16-digit system is printed. If you want to see SI as it is, then you should let the compiler do 0 extensions instead of
Symbol extension (the binary left complement 0 instead of the complement symbol bit when extending):
sprintf (S, "%04x", (unsigned short) SI);
It's OK. Or:
unsigned short si =-1;
sprintf (S, "%04x", si);
sprintf and printf can also print an integer string in 8, using "%o". Note that 8 and 16 are not going to hit.
A negative number is an unsigned, in fact, a direct 16-or 8-binary representation of the internal encoding of the variable.
Control floating-point printing format
The printing and formatting control of floating point numbers is another common function of sprintf, floating point numbers use the format character "%f" control, default security
Leave 6 digits after the decimal point, such as:
sprintf (S, "%f", 3.1415926); Produce "3.141593"
But sometimes we want to control the width and scale of the print, and 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. Like what:
sprintf (S, "%10.3f", 3.1415626); Produced: "3.142"
sprintf (S, "%-10.3f", 3.1415626); Produced: "3.142"
sprintf (S, "%.3f", 3.1415626); Do not specify the total width, resulting in: "3.142"
Pay attention to a question, you guess.
int i = 100;
sprintf (S, "%.2f", I);
What you're going to do. "100.00". Is that right. Try it yourself, and try the following:
sprintf (S, "%.2f", (double) i);
The first one is definitely not the correct result, as mentioned earlier, the parameter pressure stack when the caller does not know with I
The corresponding format control character is a "%f". The function itself does not know that when it was pressed into the stack it was an integer,
So the 4 bytes of the poor saved integer I were use robust reporting as floating-point numbers, and the whole mess was gone.
However, if someone is interested in using a floating-point number to encode manually, then you can use this method to test your hand
Is the result of the work arrangement correct.?
Character/ascii Code Control
We know that in C/s + + languages, char is also a common type of scalable, except for word length, which is associated with short,
Int,long These types are not fundamentally different, but are used to represent characters and strings. (Perhaps it was time to
This type is called "byte", and it is now possible to use byte or short to set char through a TypeDef, depending on the actual situation.
Righteousness comes out, this is more appropriate)
So, using "%d" or "%x" to print a character, you can get its 10-or 16-bit ASCII;
To print an integer with "%c", you can see the ASCII characters it corresponds to. The following program segment puts all the visible characters
The ASCII Code table is printed to the screen (printf here, note that "#" when combined with "%x" automatically adds "0X" to the 16 number)
Prefix):
for (int i = i < 127; i++) {
printf ("[%c]:%3d 0x% #04X \ n", I, I, I);
}
Connection String
sprintf's format control string can be inserted into a variety of things, and eventually "connected to a string", nature will be able to even
String, which can replace Strcat on many occasions, but sprintf can connect multiple strings at once (naturally
Insert something else in between them, which is very flexible anyway. Like what:
char* who = "I";
char* whom = "CSDN";
sprintf (S, '%s love%s ', who, whom); Produce: "I love CSDN." "
Strcat can only connect strings (an array of characters that end with ', "or called character Buffering, null-terminated-string),
But sometimes we have two-segment character buffers, and they don't end with ' a '. For example, many characters returned from third party library functions
Group, a stream of characters that is read in a hardware or network transmission, which does not necessarily have a corresponding ' "' to be followed by each sequence of characters.
Tail. If the direct connection, whether sprintf or strcat will certainly lead to illegal memory operations, and Strncat also requires at least the first
One argument is a null-terminated-string, so what should I do? We will naturally recall the previous introduction printing integers and floating-point numbers
You can specify the width, and the string is the same. Like what:
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!
There's a nine-to-ten problem. Can be changed to:
sprintf (S, "%7s%7s", a1, A2);
is not good to go, the right should be:
sprintf (S, "%.7s%.7s", a1, A2);//produce: "ABCDEFGHIJKLMN"
This can be likened to the "%m.nf" of the printed floating-point number, and in "%m.ns", m represents the width (empty when the string is short)
Grid, which is printed according to the actual width, n represents the maximum number of characters taken from the corresponding string. Usually in the print word
The string when m is not much use, or the point of the number of n after the use of more. Naturally, you can also take only a subset of the characters before and after:
sprintf (S, "%.6s%.5s", a1, A2);//produce: "ABCDEFHIJKL"
In many cases, we may also want the numbers in these format controllers to specify length information to be dynamic rather than
Statically specified, because many times the program will not be able to know exactly what characters are needed in the array of characters to run.
Dynamic width/Precision setting is also taken into account in the implementation of sprintf, sprintf uses "*" to occupy a
The position of a constant number that specifies the width or precision, as well as the actual width or precision that can be used with other printed variables.
Sample is provided, so the above example can be changed to:
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, and so on are all dynamically assigned to those constant values, such as:
sprintf (S, "%-*d", 4, ' A '); Produce "65"
sprintf (S, "% #0 *x", 8, 128); Produces "0x000080", "#" produces 0X
sprintf (S, "%*.*f", 10, 2, 3.1415926); Produce "3.14"
Print address information
Sometimes when debugging a program, we might want to look at the address of some variable or member, because the address or pointer is just a 32-digit number, you can print them out using "%u" that prints unsigned integers:
sprintf (S, "%u", &i);
But usually people prefer to use 16 instead of 10 to display an address:
sprintf (S, "%08x", &i);
However, these are indirect methods, 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);
Using the return value of sprintf
Less attention is paid to the return value of the printf/sprintf function, but sometimes it is useful, SPRITNF returns the function call
The number of characters that are eventually printed into the character buffer. That is, you don't need to call again once the Sprinf call is over
Strlen already knew the length of the result string. Such as:
int len = sprintf (S, "%d", I);
For a positive integer, Len equals the 10-digit number of the integer i.
The following is a complete example that generates random numbers between 10 [0, 100) and prints them into a character array s,
separated by commas.
#include
#include
#include
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 line break.
printf (s);
return 0;
}
Imagine when you take a record out of a database, and then want to connect their fields to a single word in some sort of rule.
String, you can use this method theoretically, he should be more efficient than the constant strcat, because strcat each call
All need to find the final ' sprintf ' position, and in the example given above, each time we use the return value of the
A place to write it down directly.
frequently asked questions about using sprintf
sprintf is a variable parameter function that often goes wrong when used, and as long as the problem is usually a memory visit that can cause the program to crash
Ask the wrong, but fortunately by sprintf misuse caused by the problem, although serious, but very easy to find, nothing but a few cases, pass
Common eyes and then the wrong code to look at a few more eyes to see it.
1>> Buffer Overflow
The length of the first parameter is too short to say, give it a bigger spot. Of course also may be the back of the argument to ask
, we suggest that the argument should be careful, and when printing a string, try to use the form "%.NS" to specify the maximum number of characters.
2>> forgot the first argument
The low-level can no longer be a low-level problem, used to use printf too accustomed.
3>> Variable parameter correspondence problem
Usually forget to provide a corresponding format of the variable parameter, resulting in all the wrong parameters, check and check it. Especially
It is the corresponding "*" of those parameters, are provided. Instead of an integer corresponding to a "%s", the compiler will think that you
Bullied her too far.