Asam Padeh
Asam Padeh

Reputation: 145

Add one generic parameter to printf

I think it is a wrapper function to printf. For example:

my_printf("Hello world\n")

prints

[1] Hello world

or

[hh:mm:ss] Hello world

I know I see it in Linux kernel but not sure how to implement it in my own application.

In first example above, the number is incremented so the next call to my_printf will be 2. e.g

my_printf("Hello universe\n");

prints

[2] Hello universe

User is never passing generic parameter but still it is printed.

Upvotes: 2

Views: 128

Answers (3)

Scheff's Cat
Scheff's Cat

Reputation: 20141

The trick with a static variable was already mentioned.

2nd part of the puzzle is to use things offered in stdarg.h.

The last part of puzzle is vprintf() which can be used for the variable argument list.

A sample:

#include <stdio.h>
#include <stdarg.h>

int my_printf(const char *fmt, ...)
{
  static unsigned counter = 0;
  int len1 = printf("[%d] ", ++counter);
  if (len1 < 0) return len1;
  va_list args;
  va_start(args, fmt);
  int len2 = vprintf(fmt, args);
  va_end(args);
  return len2 < 0 ? len2 : len1 + len2;
}


int main(void)
{
  my_printf("Hello world.\n");
  my_printf("%s", "Hello world, again.\n");
  for (int i = 2; i <= 4; ++i) my_printf("Hello %d. world.\n", i);
}

Output:

[1] Hello world.
[2] Hello world, again.
[3] Hello 2. world.
[4] Hello 3. world.
[5] Hello 4. world.

Live Demo on coliru


If the counter should be an argument instead of a static variable, my_printf() could be adjusted resp.:

#include <stdio.h>
#include <stdarg.h>

int my_printf(unsigned counter, const char *fmt, ...)
{
  int len1 = printf("[%d] ", counter);
  if (len1 < 0) return len1;
  va_list args;
  va_start(args, fmt);
  int len2 = vprintf(fmt, args);
  va_end(args);
  return len2 < 0 ? len2 : len1 + len2;
}

int main(void)
{
  unsigned counter = 0;
  my_printf(++counter, "Hello world.\n");
  my_printf(++counter, "%s", "Hello world, again.\n");
  for (int i = 2; i <= 4; ++i) my_printf(++counter, "Hello %d. world.\n", i);
}

Live Demo on coliru

Incrementing counter in my_printf() wouldn't affect the variable passed as argument. (C is always passing arguments by value.) In that case, the counter had to be passed by pointer instead.

Upvotes: 9

Ed Heal
Ed Heal

Reputation: 59997

Here goes - I was bored

#include <stdio.h>

#define myprintf counter();printf
void counter()
{
    static int i = 0;

     printf("%d", i);
     i++;
}
int main()
{
    myprintf("Hello World %d %s", 5, "Tea");
    myprintf("Hello World %d %s", 8, "Coffee");

    return 0;
}

EDIT

As suggested

#include <stdio.h>
#define myprintf(...) do { counter(); printf(__VA_ARGS__); } while (0)

void counter()
{
    static int i = 0;

     printf("%d", i);
     i++;
}
int main()
{
    myprintf("Hello World %d %s", 5, "Tea");
    myprintf("Hello World %d %s", 8, "Coffee");

    return 0;
}

And this compiles and works!

Upvotes: 2

Angevil
Angevil

Reputation: 477

You can accomplish this by using static variables. This ain't a variable "that you supply to the function without user declares it". It is a variable that will never be instantiated more than once.

Example:

int increment ()
{
    // this line will only be "executed" on first call to increment ()
    static int count = 0;

    count += 1;
    return count;
}

Each time you will call increment (), it will return the next integer.

Upvotes: 0

Related Questions