⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdio.texi

📁 一个C源代码分析器
💻 TEXI
📖 第 1 页 / 共 5 页
字号:
In practice, it is often easier just to use @code{asprintf}, below.@end deftypefun@node Dynamic Output@subsection Dynamically Allocating Formatted OutputThe functions in this section do formatted output and place the resultsin dynamically allocated memory.@comment stdio.h@comment GNU@deftypefun int asprintf (char **@var{ptr}, const char *@var{template}, @dots{})This function is similar to @code{sprintf}, except that it dynamicallyallocates a string (as with @code{malloc}; @pxref{UnconstrainedAllocation}) to hold the output, instead of putting the output in abuffer you allocate in advance.  The @var{ptr} argument should be theaddress of a @code{char *} object, and @code{asprintf} stores a pointerto the newly allocated string at that location.Here is how to use @code{asprintf} to get the same result as the@code{snprintf} example, but more easily:@smallexample/* @r{Construct a message describing the value of a variable}   @r{whose name is @var{name} and whose value is @var{value}.} */char *make_message (char *name, char *value)@{  char *result;  asprintf (&result, "value of %s is %s", name, value);  return result;@}@end smallexample@end deftypefun@comment stdio.h@comment GNU@deftypefun int obstack_printf (struct obstack *@var{obstack}, const char *@var{template}, @dots{})This function is similar to @code{asprintf}, except that it uses theobstack @var{obstack} to allocate the space.  @xref{Obstacks}.The characters are written onto the end of the current object.To get at them, you must finish the object with @code{obstack_finish}(@pxref{Growing Objects}).@refill@end deftypefun@node Variable Arguments Output@subsection Variable Arguments Output FunctionsThe functions @code{vprintf} and friends are provided so that you candefine your own variadic @code{printf}-like functions that make use ofthe same internals as the built-in formatted output functions.The most natural way to define such functions would be to use a languageconstruct to say, ``Call @code{printf} and pass this template plus allof my arguments after the first five.''  But there is no way to do thisin C, and it would be hard to provide a way, since at the C languagelevel there is no way to tell how many arguments your function received.Since that method is impossible, we provide alternative functions, the@code{vprintf} series, which lets you pass a @code{va_list} to describe``all of my arguments after the first five.''Before calling @code{vprintf} or the other functions listed in thissection, you @emph{must} call @code{va_start} (@pxref{VariadicFunctions}) to initialize a pointer to the variable arguments.  Then youcan call @code{va_arg} to fetch the arguments that you want to handleyourself.  This advances the pointer past those arguments.Once your @code{va_list} pointer is pointing at the argument of yourchoice, you are ready to call @code{vprintf}.  That argument and allsubsequent arguments that were passed to your function are used by@code{vprintf} along with the template that you specified separately.In some other systems, the @code{va_list} pointer may become invalidafter the call to @code{vprintf}, so you must not use @code{va_arg}after you call @code{vprintf}.  Instead, you should call @code{va_end}to retire the pointer from service.  However, you can safely call@code{va_start} on another pointer variable and begin fetching thearguments again through that pointer.  Calling @code{vprintf} does notdestroy the argument list of your function, merely the particularpointer that you passed to it.GNU C does not have such restrictions.  You can safely continue to fetcharguments from a @code{va_list} pointer after passing it to@code{vprintf}, and @code{va_end} is a no-op.  (Note, however, thatsubsequent @code{va_arg} calls will fetch the same arguments which@code{vprintf} previously used.)Prototypes for these functions are declared in @file{stdio.h}.@pindex stdio.h@comment stdio.h@comment ANSI@deftypefun int vprintf (const char *@var{template}, va_list @var{ap})This function is similar to @code{printf} except that, instead of takinga variable number of arguments directly, it takes an argument listpointer @var{ap}.@end deftypefun@comment stdio.h@comment ANSI@deftypefun int vfprintf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap})This is the equivalent of @code{fprintf} with the variable argument listspecified directly as for @code{vprintf}.@end deftypefun@comment stdio.h@comment ANSI@deftypefun int vsprintf (char *@var{s}, const char *@var{template}, va_list @var{ap})This is the equivalent of @code{sprintf} with the variable argument listspecified directly as for @code{vprintf}.@end deftypefun@comment stdio.h@comment GNU@deftypefun int vsnprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, va_list @var{ap})This is the equivalent of @code{snprintf} with the variable argument listspecified directly as for @code{vprintf}.@end deftypefun@comment stdio.h@comment GNU@deftypefun int vasprintf (char **@var{ptr}, const char *@var{template}, va_list @var{ap})The @code{vasprintf} function is the equivalent of @code{asprintf} with thevariable argument list specified directly as for @code{vprintf}.@end deftypefun@comment stdio.h@comment GNU@deftypefun int obstack_vprintf (struct obstack *@var{obstack}, const char *@var{template}, va_list @var{ap})The @code{obstack_vprintf} function is the equivalent of@code{obstack_printf} with the variable argument list specified directlyas for @code{vprintf}.@refill@end deftypefunHere's an example showing how you might use @code{vfprintf}.  This is afunction that prints error messages to the stream @code{stderr}, alongwith a prefix indicating the name of the program(@pxref{Error Messages}, for a description of @code{program_invocation_short_name}).@smallexample@group#include <stdio.h>#include <stdarg.h>voideprintf (const char *template, ...)@{  va_list ap;  extern char *program_invocation_short_name;  fprintf (stderr, "%s: ", program_invocation_short_name);  va_start (ap, count);  vfprintf (stderr, template, ap);  va_end (ap);@}@end group@end smallexample@noindentYou could call @code{eprintf} like this:@smallexampleeprintf ("file `%s' does not exist\n", filename);@end smallexampleIn GNU C, there is a special construct you can use to let the compilerknow that a function uses a @code{printf}-style format string.  Then itcan check the number and types of arguments in each call to thefunction, and warn you when they do not match the format string.For example, take this declaration of @code{eprintf}:@smallexamplevoid eprintf (const char *template, ...)        __attribute__ ((format (printf, 1, 2)));@end smallexample@noindentThis tells the compiler that @code{eprintf} uses a format string like@code{printf} (as opposed to @code{scanf}; @pxref{Formatted Input});the format string appears as the first argument;and the arguments to satisfy the format begin with the second.@xref{Function Attributes, , Declaring Attributes of Functions,gcc.info, Using GNU CC}, for more information.@node Parsing a Template String@subsection Parsing a Template String@cindex parsing a template stringYou can use the function @code{parse_printf_format} to obtaininformation about the number and types of arguments that are expected bya given template string.  This function permits interpreters thatprovide interfaces to @code{printf} to avoid passing along invalidarguments from the user's program, which could cause a crash.All the symbols described in this section are declared in the headerfile @file{printf.h}.@comment printf.h@comment GNU@deftypefun size_t parse_printf_format (const char *@var{template}, size_t @var{n}, int *@var{argtypes})This function returns information about the number and types ofarguments expected by the @code{printf} template string @var{template}.The information is stored in the array @var{argtypes}; each element ofthis array describes one argument.  This information is encoded usingthe various @samp{PA_} macros, listed below.The @var{n} argument specifies the number of elements in the array@var{argtypes}.  This is the most elements that@code{parse_printf_format} will try to write.@code{parse_printf_format} returns the total number of arguments requiredby @var{template}.  If this number is greater than @var{n}, then theinformation returned describes only the first @var{n} arguments.  If youwant information about more than that many arguments, allocate a biggerarray and call @code{parse_printf_format} again.@end deftypefunThe argument types are encoded as a combination of a basic type andmodifier flag bits.@comment printf.h@comment GNU@deftypevr Macro int PA_FLAG_MASKThis macro is a bitmask for the type modifier flag bits.  You can writethe expression @code{(argtypes[i] & PA_FLAG_MASK)} to extract just theflag bits for an argument, or @code{(argtypes[i] & ~PA_FLAG_MASK)} toextract just the basic type code.@end deftypevrHere are symbolic constants that represent the basic types; they standfor integer values.@table @code@comment printf.h@comment GNU@item PA_INT@vindex PA_INTThis specifies that the base type is @code{int}.@comment printf.h@comment GNU@item PA_CHAR@vindex PA_CHARThis specifies that the base type is @code{int}, cast to @code{char}.@comment printf.h@comment GNU@item PA_STRING@vindex PA_STRINGThis specifies that the base type is @code{char *}, a null-terminated string.@comment printf.h@comment GNU@item PA_POINTER@vindex PA_POINTERThis specifies that the base type is @code{void *}, an arbitrary pointer.@comment printf.h@comment GNU@item PA_FLOAT@vindex PA_FLOATThis specifies that the base type is @code{float}.@comment printf.h@comment GNU@item PA_DOUBLE@vindex PA_DOUBLEThis specifies that the base type is @code{double}.@comment printf.h@comment GNU@item PA_LAST@vindex PA_LASTYou can define additional base types for your own programs as offsetsfrom @code{PA_LAST}.  For example, if you have data types @samp{foo}and @samp{bar} with their own specialized @code{printf} conversions,you could define encodings for these types as:@smallexample#define PA_FOO  PA_LAST#define PA_BAR  (PA_LAST + 1)@end smallexample@end tableHere are the flag bits that modify a basic type.  They are combined withthe code for the basic type using inclusive-or.@table @code@comment printf.h@comment GNU@item PA_FLAG_PTR@vindex PA_FLAG_PTRIf this bit is set, it indicates that the encoded type is a pointer tothe base type, rather than an immediate value.For example, @samp{PA_INT|PA_FLAG_PTR} represents the type @samp{int *}.@comment printf.h@comment GNU@item PA_FLAG_SHORT@vindex PA_FLAG_SHORTIf this bit is set, it indicates that the base type is modified with@code{short}.  (This corresponds to the @samp{h} type modifier.)@comment printf.h@comment GNU@item PA_FLAG_LONG@vindex PA_FLAG_LONGIf this bit is set, it indicates that the base type is modified with@code{long}.  (This corresponds to the @samp{l} type modifier.)@comment printf.h@comment GNU@item PA_FLAG_LONG_LONG@vindex PA_FLAG_LONG_LONGIf this bit is set, it indicates that the base type is modified with@code{long long}.  (This corresponds to the @samp{L} type modifier.)@comment printf.h@comment GNU@item PA_FLAG_LONG_DOUBLE@vindex PA_FLAG_LONG_DOUBLEThis is a synonym for @code{PA_FLAG_LONG_LONG}, used by convention witha base type of @code{PA_DOUBLE} to indicate a type of @code{long double}.@end table@ifinfoFor an example of using these facilitles, see @ref{Example of Parsing}.@end ifinfo@node Example of Parsing@subsection Example of Parsing a Template StringHere is an example of decoding argument types for a format string.  Weassume this is part of an interpreter which contains arguments of type@code{NUMBER}, @code{CHAR}, @code{STRING} and @code{STRUCTURE} (andperhaps others which are not valid here).@smallexample/* @r{Test whether the @var{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -