How does printf locate and replace %s 's? [duplicate] - c

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
source code of c/c++ functions
I was wondering where I can find the C code that's used so that when I write printf("Hello World!"); in my C programm to know that it has to print that string to STDOUT. I looked in <stdio.h>, but there I could only find its prototype int printf(const char *format, ...), but not how it looks like internally.

Here's the GNU version of printf... you can see it passing in stdout to vfprintf:
__printf (const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);
return done;
}
See here.
Here's a link to vfprintf... all the formatting 'magic' happens here.
The only thing that's truly 'different' about these functions is that they use varargs to get at arguments in a variable length argument list. Other than that, they're just traditional C. (This is in contrast to Pascal's printf equivalent, which is implemented with specific support in the compiler... at least it was back in the day.)

Related

C passing ... to a function [duplicate]

This question already has answers here:
How to wrap printf() into a function or macro?
(8 answers)
call printf using va_list
(4 answers)
Closed 4 years ago.
I am working on making a version of printf in an embedded system that will print over a variety of interfaces. I am using snprintf to create the string and then sending it out over the interface. My curiosity is what the "..." being passed into the function is. The printf that I am using looks like, this is taken from an embedded printf library
void u_printf(const char* format, ...)
In this case the ... is some number of assorted variables passed into the function. But if I want to write my own version of this how do I get those variables passed in so I can then pass them on to snprintf.
void u_printf(const char* format, ...){
int cx;
char buffer[100];
cx = x_snprintf(buffer, 100, format, ??);
// function to send buffer to interface goes here
}
So how do I go about getting the ... variables passed in to where the ?? mark is? Thanks!
Some quick help revealed that va_list is the answer here. When the ... is present we can grab the arguments passed in by creating va_list va variable. This can then be used or passed to vsnprintf()

Learning to use GCC

I am a student of computer science and for reasons beyond my comprehension i have only been taught to code in the TURBO compiler.
But now i have realized that i should learn to code in GCC. The problem is that i dont know any of the header files and therefore i am not able to use any of the built in functions.
All the GCC tutorials i have seen are for beginners. I am at more of an intermediate state of learning and hence if any of you know of a book or a website where i can learn the details about the header files then it would be helpful.
NOTE: just to be clear-i am a linux user.
Conio.h is not the standard header file it is available only in turbo c compiler
Check out these links
http://www.gnu.org/s/hello/manual/libc/index.html
http://www.di-mgt.com.au/src/CStdLib.html
and the previous stackoverflow question List of standard header files in C and C++
http://gcc.gnu.org/onlinedocs/gcc/
http://linux.die.net/man/1/gcc
http://www.cplusplus.com/reference/clibrary/
http://en.wikipedia.org/wiki/C_standard_library
http://publications.gbdirect.co.uk/c_book/
http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html
Most of the header files used by gcc are either C C++ or POSIX compliant. Therefore you need to learn the language. printf is in stdio.h in every C compiler that is standards compliant.
There are specific linux ones but you probably dont care about those. If you ware using a linux system the 'man' command is your friend - but it tells you the header file.
man 3 printf
produces
NAME
printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - formatted output conversion
SYNOPSIS
#include <stdio.h>
....
Like if you want to use printf() (for eg..), just type man printf (man stands for manual) in your terminal if Linux or in google and you'l get all the thing you need to use printf:
Synopsis
#include <stdio.h>
int printf (const char *format, ...);
int fprintf (FILE *stream, const char *format, ...);
int sprintf (char *str, const char *format, ...);
int snprintf (char *str, size_t size, const char *format, ...);
#include <stdarg.h>
int vprintf (const char *format, va_list ap);
int vfprintf (FILE *stream, const char *format, va_list ap);
int vsprintf (char *str, const char *format, va_list ap);
int vsnprintf (char *str, size_t size, const char *format, va_list ap);
Then to use printf(), you see that you need to include stdio.h:
#include <stdio.h>
Normally you can compile without including it but it gives you warning..
Moreover use <> to include standart header files and "" to include your headers like: #include "myHeaderinMyLocalFolder.h"
If TURBO-C (which I guess you meant) is anything like TURBO-PASCAL, with it's library of console functions, there is nothing like that in standard C. And standard C is what is usedby gcc, so if you know how to use the functions in e.g. stdio.h then there is not much difference.

Code for printf function in C [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
source code of c/c++ functions
I was wondering where I can find the C code that's used so that when I write printf("Hello World!"); in my C programm to know that it has to print that string to STDOUT. I looked in <stdio.h>, but there I could only find its prototype int printf(const char *format, ...), but not how it looks like internally.
Here's the GNU version of printf... you can see it passing in stdout to vfprintf:
__printf (const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);
return done;
}
See here.
Here's a link to vfprintf... all the formatting 'magic' happens here.
The only thing that's truly 'different' about these functions is that they use varargs to get at arguments in a variable length argument list. Other than that, they're just traditional C. (This is in contrast to Pascal's printf equivalent, which is implemented with specific support in the compiler... at least it was back in the day.)

How to use __VA_ARGS__ inside a C function instead of macro? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
C/C++: Passing variable number of arguments around
I'm currently using the following macro declared on my C file.
#define COMMON_Print(...) printf (__VA_ARGS__)
Now that call works just fine, but turns out that I need to be able to create a C function that looks something like this:
void COMMON_Print(...)
{
printf (__VA_ARGS__);
}
So that function doesn't work, I get an error
"Error : undefined identifier __VA_ARGS__"
The complexity of my project requires to have a function since it's an interface... So how can I get the parameters ... and pass them to the printf function? Or better what am I doing wrong?
Thanks!
Each of the ?printf functions has a corresponding v?printf function which does the same thing but takes a va_list, a variable argument list.
#include <stdio.h>
#include <stdarg.h>
void COMMON_Print(char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
Side note: Notice that va_start takes the name of the last argument before the ... as a parameter. va_start is a macro which does some stack-based magic to retrieve the variable arguments and it needs the address of the last fixed argument to do this.
As a consequence of this, there has to be at least one fixed argument so you can pass it to va_start. This is why I added the format argument instead of sticking with the simpler COMMON_Print(...) declaration.
See: http://www.cplusplus.com/reference/clibrary/cstdio/vprintf/
__VA_ARGS__ is only for macros; variadic functions are rather different. You need to use va_start, va_arg and va_end from stdarg.h to handle them.
First, your function needs at least one named parameter, e.g.:
void COMMON_Print(const char* fmt, ...)
Then you can define a va_list and use va_start to set it:
va_list args;
va_start(args, fmt);
// your code here
va_end(args);
Now you can use args to access the arguments; calling va_arg(args, TYPE) will return the next variadic argument, so you can just keep calling that until you've read all the arguments.
If you're just trying to call printf, there's a printf variant called vprintf that takes the va_list directly:
vprintf(fmt, args);
There is no easy way to call one variadic function from another; you need something like vprintf that takes the whole va_list
__VA_ARGS__ is for macros only.
Chaining the variable number of argument to another function can't be done directly. Instead you have to
pass a va_list , and the function you're calling have to take a va_list. Luckily there's a variation of printf that does this, your function have to be written this way:
void COMMON_Print(char *format,...)
{
va_list args;
va_start(args,format);
vprintf(format,args);
va_end(args);
}
What you are looking for is the Ellipsis operator.

what's the difference between the printf and vprintf function families, and when should I use one over the other?

I understand that the difference between the printf, fprintf, sprintf etc functions and the vprintf, vfprintf, vsprintf etc functions has to do with how they deal with the function arguments. But how specifically? Is there really any reason to use one over the other? Should I just always use printf as that is a more common thing to see in C, or is there a legitimate reason to pick vprintf instead?
printf() and friends are for normal use. vprintf() and friends are for when you want to write your own printf()-like function. Say you want to write a function to print errors:
int error(char *fmt, ...)
{
int result;
va_list args;
va_start(args, fmt);
// what here?
va_end(args);
return result;
}
You'll notice that you can't pass args to printf(), since printf() takes many arguments, rather than one va_list argument. The vprintf() functions, however, do take a va_list argument instead of a variable number of arguments, so here is the completed version:
int error(char *fmt, ...)
{
int result;
va_list args;
va_start(args, fmt);
fputs("Error: ", stderr);
result = vfprintf(stderr, fmt, args);
va_end(args);
return result;
}
You never want to use vprintf() directly, but it's incredibly handy when you need to e.g. wrap printf(). For these cases, you will define the top-level function with variable arguments (...). Then you'll collect those into a va_list, do your processing, and finally call vprintf() on the va_list to get the printout happening.
The main difficulty with variadic arguments is not that there is a variable number of arguments but that there is no name associated with each argument. The va_start, va_arg macros parse the arguments in memory (in most C compilers they are on the stack) using the type information contained in the format string cf. Kernighan and Ritchie, second edition, section 7.3.
This example shows the elegance of Python. Since C/C++ cannot reconcile the difference between int error(char *fmt, ...) and int error(char *fmt, va_list ap), thus, for every function *printf, it has to create two versions, i.e., one taking in ..., the other taking in va_list, this essentially doubles the total number of functions. In Python, you can use *list() or **dict() to pass in a va_list as ....
Hopefully, future C/C++ can support this kind of argument processing scheme.

Resources