Sprintf usage)

Source: Internet
Author: User
Tags 04x clear screen control characters
Printf may be the second function that many programmers encounter when learning C language (I guess the first function is main). It is naturally an old friend. However, do you know much about this old friend? Do you know more about sprintf? 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. So this article focuses on sprintf, which is sometimes interspersed with pritnf.

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. 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 (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.

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, 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.
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 ". 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. 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, it is used to represent characters and strings. (This type may be 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)
Therefore, print a character using "% d" or "% x" to obtain its 10-or 16-digit ASCII code. In turn, print an integer using "% C" to see its ASCII characters. The following section prints the ASCII code table of all visible characters to the screen (printf is used here, note that "#" and "% x" are automatically prefixed with "0x" in hexadecimal notation ):

For (INT I = 32; I <127; I ++ ){

Printf ("[% C]: % 3d 0x % # 04x \ n", I, I );

}

3. 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 '\ 0' or a character buffer, null-terminated-string), but sometimes we have two character buffers, they do not end with '\ 0. For example, many character arrays returned from third-party library functions, and hidden streams read from hardware or network transmission, they may not end with a corresponding '\ 0' 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 ", in" % 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"
4. Print the 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 );
5. Use the sprintf 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 into an array of characters (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 <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 last '\ 0' position, and in the example given above, every time we use the sprintf return value to write down this position directly.
6. FAQs 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 a memory access error that can cause the program to crash, but fortunately the problems caused by sprintf misuse are serious, but it is easy to find out, nothing more than a few situations, usually with the eyes of the error code to see a few more eyes.
? 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 a problem with the following parameters. We recommend that you be careful with the corresponding parameters. When printing a string, try to 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. Are all parameters corresponding to "*" provided? Do not map an integer to a "% s". The compiler will think that you are deceiving her too much (the compiler is the mother of OBJ and exe, which should be a female: P ).
7. strftime
Sprintf also has a good cousin: strftime, which is specially used to format the time string. Its usage is very similar to that of her cousin. It is also a lot of format control characters, but after all, the girl's family is fine, she also needs the caller to specify the maximum length of the buffer, probably to shirk responsibility in case of problems. 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 in MFC: cstring: format. strftime also has her same path in MFC: ctime: format, the code used to write is more elegant because of the sponsorship of the object-oriented program.

8. Postscript
All of the functions described in this article can be easily found in msdn. based on my own experience and some examples, I will use some common and useful functions, I may have introduced some usage that many beginners don't know. I hope you don't want to joke or criticize and correct it.
Some people think that this function with variable parameters will cause various problems and therefore it is not recommended to use it. However, I have never been able to resist the temptation of their powerful functions and have been using them in practical work. In fact, C #. Net supports variable parameters from the beginning, and java5.0, which was just released, also supports variable parameters.

Thanks to ericzhangali (another space) for carefully reviewing the entire article, correcting many small mistakes and providing some suggestions. I would also like to thank laomai for reading the entire article and providing suggestions for adding and deleting some content.

① Obtain the system time: void getsystemtime (lpsystemtime); The following is an example:
# Include <windows. h>
# Include <stdio. h>
# Include <stdlib. h>
Void main (){
Systemtime st; // defines the struct of the storage time
Char strtime [256];
Int n = 0;
Getsystemtime (& St );
N = sprintf (strtime, "Year: \ t % d \ n", st. wyear );
N + = sprintf (strtime + N, "month: \ t % d \ n", st. wmonth );
N + = sprintf (strtime + N, "Day: \ t % d \ n", st. wday );
N + = sprintf (strtime + N, "date: \ t % d \ n", st. wdayofweek );
N + = sprintf (strtime + N, "hour: \ t % d \ n", st. whour );
N + = sprintf (strtime + N, "minute: \ t % d \ n", st. wminute );
N + = sprintf (strtime + N, "Second: \ t % d \ n", st. wsecond );
N + = sprintf (strtime + N, "millisecond: \ t % d \ n", st. wmilliseconds );

Printf ("% s", strtime );
System ("pause ");
}
**************************************** **
A parameter table is a series of parameters that need to be output. The number of parameters must be the same as that described in the formatted string.
There are as many parameters as they are. "," are used to separate them and the order is one-to-one. Otherwise, you may want
Error.
1. format the operator
The formatting rules provided by Turbo c2.0 are as follows:
When there are too many threads, there are too many threads, too many threads.
Symbol function
── ─
% D decimal signed integer
% U decimal unsigned integer
% F floating point number
% S string
% C single character
% P pointer Value
% E exponential floating point number
% X, % x unsigned integer in hexadecimal format
% 0 unsigned integer in octal format
% G automatically selects the appropriate notation
When there are too many threads, there are too many threads, too many threads.
Note:
(1). You can insert a number between "%" and a letter to indicate the largest field width.
For example, % 3d indicates that three integer values are output, and the three digits are not right aligned.
% 9.2f indicates the floating point number with the output field width of 9, where the decimal point is 2 and the integer is 6,
The decimal point occupies one place, which is not 9 digits right-aligned.
% 8 s indicates the output string of 8 characters, which is not 8 characters in the right alignment.
If the length of a string, or the number of integer digits exceeds the field width, It is output according to the actual length.
However, for floating-point numbers, if the number of digits in the integer part exceeds the width of the entire digit, the data is output according to the actual integer;
If the decimal point width exceeds the specified decimal point width, the output is rounded to the specified width.
In addition, if you want to add some 0 before the output value, you should add 0 before the field width.
For example, % 04d indicates that when a value smaller than four digits is output, 0 is added before to make the total width
The value is 4 digits.
If a floating point is used to represent the output format of a character or integer, the number after the decimal point represents the maximum width,
The number before the decimal point represents the minimum width.
For example, % 6.9 s indicates that a string with a length of not less than 6 and not greater than 9 is displayed. If the value is greater than 9
Content after 9th characters will be deleted.
(2) You can add the lower-case letter l between "%" and the letter to indicate that the output is a long number.
For example, % LD indicates the output long integer.
% Lf indicates that the double floating point number is output.
(3) You can control the Left or Right alignment of the output, that is, you can add a "-" number between "%" and letters.
The output is left-aligned. Otherwise, the output is right-aligned.
For example, %-7d indicates that the output 7-digit integer is left aligned.
%-10 s indicates that the output is left aligned with 10 Characters
2. Some special characters
When there are too many threads, there are too many threads, too many threads.
Character Function
── ─
\ N line feed
\ F clear screen and change pages
\ R press ENTER
\ T Tab character
\ Xhh indicates an ascii code in hexadecimal notation,
HH indicates one to two hexadecimal numbers.
When there are too many threads, there are too many threads, too many threads.

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.