Original address:
http://blog.csdn.net/liukun321/article/details/5633249
SPRINTF series functions and variable parameter functions collection
The sprintf function is defined as follows:
int sprintf (char * szbuffer, const char * szformat, ...);
The first argument is a character buffer, followed by a format string. sprintf is not the format result standard
Output, but it is deposited into the szbuffer. The function returns the length of the string. Programming in text mode
In
printf ("The sum of%i and%i is%i", 5, 3, 5+3);
Has the same functionality as
Char szbuffer [100];
sprintf (Szbuffer, "The sum of%i and%i is%i", 5, 3, 5+3);
Puts (szbuffer);
Almost everyone has experienced that when a format string is inconsistent with a variable that is being formatted, it may cause printf to execute
Error and may cause the program to be dropped. Not only do you have to worry about this when using sprintf, but there's also a new
Burden: The string buffer you define must be large enough to hold the result. Microsoft Specialized Functions _snprin
TF solves this problem by introducing another parameter that represents the size of the buffer computed in characters.
Vsprintf is a variant of sprintf, which has only three parameters. VSPRINTF is used to execute a parameter with multiple
Custom functions, similar to printf format. The first two parameters of vsprintf are the same as sprintf: one for saving
The resulting character buffer and a format string. The third parameter is a pointer to the formatted parameter array.
In effect, the pointer points to a variable in the stack for a function call. Va_list, Va_start, and Va_end macros (
defined in STDARG.H) help us process the stack pointer. The final Scrnsize program in this chapter shows you how to use these macros. Using the vsprintf function, the sprintf function can be written like this:
int sprintf (char * szbuffer, const char * szformat, ...)
{
int ireturn;
Va_list PArgs;
Va_start (PArgs, Szformat);
Ireturn = vsprintf (Szbuffer, Szformat, PArgs);
Va_end (PArgs);
return ireturn;
}
The Va_start macro sets PARG to point to a stack variable address that is on the stack parameter Szformat
Surface.
Because many of the Windows early programs used sprintf and vsprintf, Microsoft was eventually led to Windo
Two similar functions are added to the WS API. The wsprintf and wvsprintf functions of windows are functionally associated with
sprintf and vsprintf are the same, but they cannot handle floating-point formats.
Of course, as the wide character is published, the function of the sprintf type increases a lot, making the function name extremely mixed
Mess Table 2-1 lists all the sprintf functions supported by Microsoft's C-Runtime link library and Windows.
Table 2-1
ascii wide character general
The number of variables in the parameter &NBSP
Standard Edition sprintf swprintf _stprintf
Max length edition _snprintf _snwprintf _sntprintf
Windows edition wsprintfa wsprintfw wsprintf
Index of parameter array
Standard Edition vsprintf vswprintf _vstprintf
Max length version _vsnprintf _vsnwprintf _vsntprintf
Windows version WVSPRINTFA WVSPRINTFW wvsprintf
In the wide-character version of the sprintf function, define the string buffer as a wide string. In the wide character version of all
In these functions, the format string must be a wide string. However, you must ensure that the functions that are passed to their
Its string must also consist of a wide character.
==================================
Here is another example that illustrates the use of Va_arg macros.
Include <stdio.h>
#include "Stdarg.h"
void Array_set (char* parray, ...)
{
Va_list va;
int n = 0;
char c = 0;
Va_start (VA, parray);
while (1)
{
c = va_arg (VA, char);
if (c!= 0)
{
parray[n++] = c;
}
Else
{
Break
}
}
Va_end (VA);
}
This is the example code that I test, note array_set last parameter 0, I also need to revise array_set.
At least you should not manually add a terminator.
int main ()
{
Char arr[10];
Array_set (arr,48,49,49,49,49,49,49,0); Here needs a 0来 terminator string
printf ("%s", arr);
GetChar ();
}
================================================================
The following article describes the use of variable parameter functions, explained in more detail:
Variable parameter usage in C language--
(i) write a simple variable parameter of c function
Let's explore how to write a simple variable-parameter c function. Write variable parameters
The C function uses the following macros in your program:
void Va_start (Va_list arg_ptr, Prev_param);
Type Va_arg (va_list arg_ptr, type);
void Va_end (Va_list arg_ptr);
VA here is the meaning of the variable-argument (variable parameter).
These macros are defined in Stdarg.h, so programs that use variable parameters should contain this
Header file. Here we write a simple variable-parameter function that has at least one integer
Argument, and the second argument is an integer, which is optional. The function simply prints the values of the two parameters.
void Simple_va_fun (int i, ...)
{
Va_list arg_ptr;
int j=0;
Va_start (arg_ptr, i);
J=va_arg (arg_ptr, int);
Va_end (ARG_PTR);
printf ("%d%d/n", I, j);
Return
}
We can declare our functions in our header file in this way:
extern void Simple_va_fun (int i, ...);
We can call this in the program:
Simple_va_fun (100);
Simple_va_fun (100,200);
As you can see from the implementation of this function, we should have the following steps with variable parameters:
1 first in the function to define a va_list type of variable, here is arg_ptr, this variable
Quantity is a pointer to a parameter.
2) and then using the Va_start macro to initialize the variable arg_ptr, the second parameter of the macro is the first
The previous parameter of a variable parameter is a fixed parameter.
3) then returns the variable parameter with Va_arg and assigns the value to the integer J. Va_arg's second
The parameter is the type of the parameter you want to return, and here is the int type.
4 finally using the Va_end macro to end the acquisition of variable parameters. And then you can make it in the function
With the second argument. If the function has more than one variable parameter, call Va_arg
Take each parameter.
If we use the following three methods to invoke, it is legal, but the result is not the same:
1) simple_va_fun (100);
The result is: 100-123456789 (values that change)
2) Simple_va_fun (100,200);
The result: 100 200
3) Simple_va_fun (100,200,300);
The result: 100 200
We see that the first invocation has errors, the second call is correct, and the third call, although the result
Correct, but there is a conflict with the original design of our function. In the following section, we explore these results
The reason and the variable parameters are handled in the compiler.
(ii) Processing of variable parameters in the compiler
We know that va_start,va_arg,va_end is defined macro in Stdarg.h,
Because of the 1 hardware platform different 2 compiler, so the definition of the macro is also different, under
Face to VC + + in the Stdarg.h x86 platform of the macro definition excerpt as follows ('/' number means line):
typedef char * VA_LIST;
#define _INTSIZEOF (N)/
((sizeof (n) +sizeof (int)-1) &~ (sizeof (int)-1))
#define VA_START (AP,V) (AP = (va_list) &v + _intsizeof (v))
#define VA_ARG (AP,T)/
(* (t *) (AP + _intsizeof (t))-_intsizeof (t))
#define VA_END (AP) (AP = (va_list) 0)
The definition of _intsizeof (n) is primarily for certain systems that require memory alignment. Letter of the C language
The number is pressed from right to left onto the stack, and figure (1) is the position in the stack where the parameters of the function are distributed. I
We see va_list is defined as char*, and some platforms or operating systems are defined as void*.
Look at the definition of va_start, defined as &v+_intsizeof (v), and &v is a fixed parameter on the stack of the
Address, so after we run Va_start (AP, v), the AP points to the first variable parameter in the heap
The address of the stack, as shown in figure:
High Address |-----------------------------|
| function return Address |
|-----------------------------|
|....... |
|-----------------------------|
| nth parameter (first variable parameter) |
|-----------------------------|<--va_start after AP Point
| n-1 parameter (last fixed parameter) |
Low Address |-----------------------------|<--&v
Figure (1)
Then, we use Va_arg () to get the variable parameter value of type T, and the above example is int type, for example, I
Take a look at the return value of the va_arg int type:
J= (* (int*) (AP + _intsizeof (int))-_intsizeof (int));
First ap+=sizeof (int), already points to the address of the next parameter. And then return
int* pointer to ap-sizeof (int), which is exactly the address of the first variable parameter in the stack
(Figure 2). Then use the * to obtain the content of this address (parameter value) to the J.
High Address |-----------------------------|
| function return Address |
|-----------------------------|
|....... |
|-----------------------------|<--va_arg after AP Point
| nth parameter (first variable parameter) |
|-----------------------------|<--va_start after AP Point
| n-1 parameter (last fixed parameter) |
Low Address |-----------------------------|<--&v
Figure (2)
Finally, the meaning of the Va_end macro, x86 platform is defined as ap= (char*) 0, so that the AP is no longer
Point to the stack, but as null. Some are directly defined as ((void*) 0) so that the compiler does not
Generates code for Va_end, such as GCC's x86 platform for Linux.
Here is a question to note: Because the address of the parameter is used for Va_start macros, the
Argument cannot be declared as a register variable or as a function or array type.
About Va_start, Va_arg, Va_end's description is these, we have to pay attention to the
The definitions of different operating systems and hardware platforms are somewhat different, but the principles are similar.
(iii) Problems to be noted in programming of variable parameters
Because of the definition macro of Va_start, Va_arg, Va_end, and so on, it seems silly,
the type and number of variable parameters are completely controlled by the program code in the function, which does not intelligently , and
recognizes the number and type of different parameters. &NBSP
Some people ask: so does printf not implement intelligent recognition parameters? That is because the function
printf analyzes the type of the parameter from the fixed parameter format string, and then calls the va_arg
To get the variable parameters. That is to say, you want to realize the intelligent recognition variable parameter is to pass
to make judgments in your own program. &NBSP
There is another problem because the compiler does not have a rigorous prototype check for variable parameter functions
lattice, Bad for programming error. If Simple_va_fun () is changed to:
void Simple_va_fun (int i, ...) &NBSP
{
va_list arg_ptr;
Char *s=null;
Va_start (arg_ptr, i);
S=va_arg (Arg_ptr, char*);
Va_end (ARG_PTR);
printf ("%d%s/n", I, s);
Return
}
The variable parameter is the char* type, and when we forget to call the function with two parameters, it appears
Core dump (Unix) or an illegal page error (window platform). But there may not be
Wrong, but the mistake is difficult to discover, does not favor us to write the high quality procedure.
Here's a reference to the compatibility of the VA series macros.
System V UNIX defines va_start as a macro with only one parameter:
Va_start (va_list arg_ptr);
and ANSI C is defined as:
Va_start (va_list arg_ptr, Prev_param);
If we want to use the definition of System V, we should use the definition in the Vararg.h header file
macros, ANSI C macros are incompatible with System V macros, and we generally use ANSI C, so
The definition of ANSI C is sufficient, and it is easy to transplant the program.
This article from Csdn Blog, reproduced please indicate the source: http://blog.csdn.net/reiskie/archive/2006/10/15/1335621.aspx