Convert numbers to string "Go" in C language

Source: Internet
Author: User
Tags 04x sprintf

The power of sprintf rarely disappoints you when constructing various types of data into strings. Since sprintf is almost the same as printf in usage, it is printed in a different destination, which prints to a string, and the latter is output directly on the command line. This also causes sprintf to be 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 first two parameter types are fixed, can be followed by any number of parameters. And its essence, obviously, is in the second parameter:
The formatted string.


Both printf and sprintf use a formatted string to specify the format of the string, using some format specifier (the form specifications) that begins with "%" in the format string to occupy a position, providing the corresponding variable in the list of arguments behind it. The final function replaces that specifier with a variable of the corresponding position, producing a string that the caller wants.

Formatting numeric strings
One of the most common applications of sprintf is to print integers into strings, so SPRITNF can be substituted for most occasions
Itoa

Such as:
The integer 123 is printed into a string stored in S.
sprintf (S, "%d", 123); Generate "123"
You can specify a width, insufficient left fill space:
sprintf (S, "%8d%8d", 123, 4567); Generated: "123 4567"
Of course, you can also align Left:
sprintf (S, "%-8d%8d", 123, 4567); Generated: "123 4567"
You can also print in 16 binary:
sprintf (S, "%8x", 4567); lowercase 16 Binary, Width 8 positions, right justified
sprintf (S, "%-8x", 4568); Uppercase 16 binary, Width 8 positions, left justified

In this way, an integer 16 binary string is easy to get, but when we are printing 16 binary content, we usually want a kind of equal width format of 0 on the left. It's easy to add a 0 to the front of the number that represents the width.
sprintf (S, "%08x", 4567); Produce: "000011d7"
The 10-binary printing above with "%d" can also use this way to the left to fill 0.


Note the problem with a symbol extension: For example, if we want to print a 16 binary representation of a short integer-1 of the memory, on the Win32 platform, a shorter type is 2 bytes, so we naturally want to print it with 4 16 digits:
Short si =-1;
sprintf (S, "%04x", si);
"FFFFFFFF", what's going on? Because SPRITNF is a variable parameter function, in addition to the previous two parameters, the following parameters are not type-safe, the function is not able to just through a "%x" can be learned that the first function call before the argument is pressed into the stack when the end is a 4-byte integer or a 2-byte short integer, so took a unified 4 byte processing mode, resulting in the parameter stack when the symbol expansion, expanded into 32-bit integer-1, when printing 4 position is not enough, the 32-bit integer 1 8-bit 16 is printed out.

If you want to see the true nature of SI, then you should let the compiler do 0 extensions instead of the symbol extension (the binary left side of the extension is 0 instead of the fill sign bit):
sprintf (S, "%04x", (unsigned short) SI);
You can do it. Or:
unsigned short si =-1;
sprintf (S, "%04x", si);


sprintf and printf can also 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
Floating-point printing and format control is another common function of sprintf, floating-point numbers use the format "%f" control, the 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. Like what:
sprintf (S, "%10.3f", 3.1415626); Generated: "3.142"
sprintf (S, "%-10.3f", 3.1415626); Generated: "3.142"
sprintf (S, "%.3f", 3.1415626); Does not specify the total width, resulting in: "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 the following:
sprintf (S, "%.2f", (double) i);
The first one is definitely not the right result, as mentioned earlier, the caller does not know that the format controller corresponding to I is a "%f" when the parameter is pressed. When the function is executed, the function itself does not know that the year was pressed into the stack is an integer, so poor to save the integer I of the 4 bytes is without any explanation forcibly as a floating-point format to explain, the whole mess. However, if someone is interested in using manually coding a floating-point number, then you can use this method to verify that the results of your manual orchestration are correct.

Character/ascii Code Control
As 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, but are used by people to represent characters and strings. (Perhaps it was time to
This type is called "byte" and can now be used to define char through a typedef using byte or short as the case may be, so that it is more appropriate to use "%d" or "%x" to print a character, and then to derive its 10-or 16-binary ASCII code In turn, using "%c" to print an integer, you can see the ASCII character it corresponds to. The following section prints the ASCII Code table of all visible characters to the screen (in this case, printf, note that the "#" and "%x" Automatically add the "0X" prefix to the 16 binary number):
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 eventually "connect" 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 (naturally
Insert something else between them, in short, very flexible. Like what:
char* who = "I";
char* whom = "CSDN";
sprintf (S, "%s love%s.", who, whom); Produce: "I love CSDN." "
Strcat can only concatenate strings (an array of characters ending in ' ' or ' character buffers, null-terminated-string), but sometimes we have two-bit buffers, and they don't end with '. For example, many of the character arrays that are returned from third-party library functions, the stream of characters that are read from hardware or network transmissions, do not necessarily end with a corresponding ' at the back of each sequence of characters. If the direct connection, whether it is sprintf or strcat will certainly lead to illegal memory operations, and Strncat also at least require the first parameter is a null-terminated-string, then what to do? We naturally recall that the previous introduction of printing integers and floating-point numbers 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 going to be a problem. Whether it can be changed to:
sprintf (S, "%7s%7s", a1, A2);
There is no better place to go, the right 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 (when the length of the string is insufficient to fill a space, beyond the actual width of the print), n represents the maximum number of characters to be taken from the corresponding string. Usually when I print a string, M is not much use, or the number behind the dot is 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 may also want the numbers in these format controls to specify length information to be dynamic, rather than statically specified, because many times the program will have to run until it is clear that a few characters in the character array need to be taken, and this dynamic width/precision setting function is sprintf is also taken into account, sprintf uses "*" to occupy a constant number where a specified width or precision is required, and the actual width or precision can be provided as the other printed variables, and 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 be dynamically specified those constant values, such as:
sprintf (S, "%-*d", 4, ' A '); Generate "65"
sprintf (S, "% #0 *x", 8, 128); Generate "0X000080", "#" to produce 0X
sprintf (S, "%*.*f", 10, 2, 3.1415926); Generate "3.14"


Print address information
Sometimes when debugging a program, we may want to look at the address of some variable or member, and because 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);
But usually people prefer to use 16 binary 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);
Take advantage of the return value of sprintf
Few people notice the return value of the printf/sprintf function, but sometimes it is useful, SPRITNF returns the function call
The number of characters that are ultimately 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 example that produces a random number 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 newline character.
printf (s);
return 0;
}
Imagine that when you take a record out of the database and then want to connect their fields to a single word in a certain rule
String, you can use this method theoretically, he should be more efficient than the constant strcat, because strcat each call
Need to find the last position, and in the example given above, we use the sprintf return value each time to
A place to write it down directly.


Frequently asked questions about using sprintf
sprintf is a variable parameter function, often problematic 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 the misuse of sprintf caused by serious problems, but it is easy to find out, is nothing more than a few cases, through
Often eyes can see the wrong code more than a few eyes.


?? Buffer overflow
The length of the first parameter is too short to say, give a bigger place. Of course, it could be the argument behind the question
, it is recommended to be careful with the argument, while printing the string, try to specify the maximum number of characters in the form "%.ns".


?? Forget the first parameter
Low-level can not be any more low-level problems, with printf used too accustomed. I often make it. :。 (


?? The change parameter corresponds to the problem
Usually forget to provide a corresponding format for a variable parameter, resulting in the subsequent parameter dislocation, check it. Especially
Are those parameters corresponding to "*" provided? Do not match an integer to a "%s", and 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 lot of format control, just after all small roomed cautious, she also wants the caller to specify the maximum length of the buffer, possibly for
You can shirk your responsibility in the event of a problem. Here's an 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 in MFC can also find his bosom friend: Cstring::format,strftime in MFC naturally also has her fellow:
Ctime::format, the pair has been sponsored from object-oriented, and the code used to write it is more elegant.

Convert numbers to string "Go" in C language

Related Article

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.