Archive

Posts Tagged ‘arguments’

Passing arguments to a TimerTask in Java

January 17, 2014 No comments

I recently talked about using TimerTask in Java. Today we will pass variables or attributes to that TimerTask. We saw in the last article variable passing to an implicit or inner class, but now we’re creating a subclass and passing arguments through the constructor.

MyTimerTask.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.TimerTask;

class MyTimerTask extends TimerTask
{
    private int times;
    private String result;
    private int tic=0;

    public MyTimerTask (int times, String arg2)
    {
    this.times=times;
    this.result=arg2;
    }

    public String toString()
    {
    return result;
    }

    public void run()
    {
    System.out.println((tic++%2==0)?"TIC":"TOC");
    if (tic%times==0)
        result+="TEN! ";
    }
}

TimerEx.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Timer;
import java.util.TimerTask;

class TimerEx {
    public static void main(String arglist[]) {
    long lonlon=0;
    Timer timer;
    timer = new Timer();

    TimerTask task = new MyTimerTask(10, "Start: ");

    timer.schedule(task, 10, 1000);
    try
        {
        Thread.sleep(11000);
        }
    catch (Exception e)
        {
        }
    System.out.println(task);
    }
}

In this example, we’ve passed two arguments: 10, “Start: “, to the TimerTask (MyTimerTask) constructor, they will be the number of times the task must be launched before writing “TEN! ” on a String. On the other hand, we’ve implemented the method toString in MyTimerTask to write the value directly with System.out.println().

Easy, but, what about passing a callback to execute the System.out.println() ¿?

Let’s write an interface for the Callback (MyTimerCallback), then we will implement MyTimerTask and then we will make TimerEx implement MyTimerCallback, so we can put this function in the main class:

MyTimerCallback.java

1
2
3
4
interface MyTimerCallback
{
    public void timerCallback(MyTimerTask t);
}

MyTimerTask.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.util.TimerTask;

class MyTimerTask extends TimerTask
{
    private int times;
    private String result="";
    private int tic=0;
    private MyTimerCallback cbClass;

    public MyTimerTask (int times, MyTimerCallback cb)
    {
    this.times=times;
    this.cbClass=cb;
    }

    public String toString()
    {
    return result;
    }

    public void run()
    {
    System.out.println((tic++%2==0)?"TIC":"TOC");
    if (tic%times==0)
        {
        result+="TEN! ";
        cbClass.timerCallback(this);
        }
    }
}

Here, in the constructor, we are asking an object type MyTimerCallback, from which we will call timerCallback().

TimerEx.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Timer;
import java.util.TimerTask;

class TimerEx implements MyTimerCallback
{
    public static void main(String arglist[])
    {
    long lonlon=0;
    Timer timer;
    timer = new Timer();

    TimerTask task = new MyTimerTask(10, new TimerEx());

    timer.schedule(task, 10, 1000);
    }

    public void timerCallback(MyTimerTask t)
    {
    System.out.println(t);
    }
}

From TimerEx, we pass a new TimerEx (as the main method is static and the class is not instanced, we must pass a new object).

Now, everytime 10 tics are executed, we will launch timerCallback(). And of course, we can do it as inner class (not instancing TimerEx, as we can see in the last example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Timer;
import java.util.TimerTask;

class TimerEx implements MyTimerCallback
{
    public static void main(String arglist[])
    {
    long lonlon=0;
    Timer timer;
    timer = new Timer();

    TimerTask task = new MyTimerTask(10, new MyTimerCallback()
        {
        public void timerCallback(MyTimerTask t)
        {
            System.out.println("Inner class: "+t);
        }
        });

    timer.schedule(task, 10, 100);
    }

    public void timerCallback(MyTimerTask t)
    {
    System.out.println(t);
    }
}

[/cc]
Foto: Rob & Stephanie Levy (Flickr) CC-by

Variable number of arguments for a function in C

October 13, 2013 No comments

If you have ever program in C, I’m sure you had met printf(), it is, probably, the first thing you used in this language (at least for a Hello World). Well, this function accepts as many arguments as keywords you enter in its first argument, so here we have a variable number of arguments.

Some people think that only printf() and scanf() functions worth it, but there are so many cases where it is needed, for example when creating a function with optional arguments (these functions are common in C++, but C doesn’t allow it so easily), when concatenating some strings, filling data variables, internationalizing, and more.

All we must do is to include stdarg.h wichi provides us the tools to make it happen.

Let’s see this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

void putargs(int nargs, ...)
{
  va_list ap;
  int i;
  int num;

  va_start(ap, nargs); // nargs, because is the last known argument
  for (i =0; i<nargs; i++)
    {
      num=va_arg(ap, int); // All arguments are int
      printf("Argument %d = %d\n", i, num);
    }
  va_end(ap);
  printf("\n");
}

int main(int argc, char *argv[])
{
  putargs(5, 6, 77, 445, 34, 23, 12, 43, 32);
  putargs(2, 23, 94);
  putargs(0);

  return EXIT_SUCCESS;
}

We can see here, function putargs() prints out values of possible arguments we’ve passed the function, being the first of them the number of arguments we have, because we have no way to count the number of arguments passed (like printf, we will use as many arguments as %[x] we have in the format string). So we will have to use different techniques to know the total number of arguments, like:

  • Ask the user, like we’ve done here, with an argument telling the function how many arguments to read.
  • Search for a value inside all arguments, we can read arguments until the value I found is 5 (for example). It is used so often when passing pointers to the function, I will read arguments until I get a NUL value.
  • Like printf() use a number of keywords, this will be the number of arguments

We just have to copy this sample code and make some test, have in mind when we start looking for arguments, we must call va_start() with a va_list variable and the last known argument we gave the function, then each time we call va_arg, we will get a different argument from the “unknown argument list”, that is the list of arguments starting by the three dots.

In the next example we will have a variable argument function used to fill a struct with people data. We will have the function new_person where we must say the name, but it will add data to the struct as you are adding arguments when you call the function, it’s fun and easy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#define MAX_STRLEN 64

struct TPersonData
{
  char name[MAX_STRLEN];
  char blog[MAX_STRLEN];
  char facebook[MAX_STRLEN];
  char twitter[MAX_STRLEN];
  char city[MAX_STRLEN];
  char drink[MAX_STRLEN];   /* Don't know anything else I can put for this example :) */
  char phone[MAX_STRLEN];
};

/* Remember always to clear data. Variable initialization is important if we don't
 want to see garbage. */

struct TPersonData cleanPerson()
{
  struct TPersonData p;
  strcpy(p.name, "");
  strcpy(p.blog, "");
  strcpy(p.facebook, "");
  strcpy(p.twitter, "");
  strcpy(p.city, "");
  strcpy(p.drink, "");
  strcpy(p.phone, "");

  return p;
}

struct TPersonData new_person (char *name, ...)
{
  va_list vl;
  char *temp;
  int num = 1;
  struct TPersonData out = cleanPerson();

  strcpy(out.name, name);

  va_start(vl, name);
 
  while ( (temp = va_arg(vl, char*))!=NULL)
    {
      switch (num++)
    {
    case 1:
      strcpy(out.blog, temp);
      break;
    case 2:
      strcpy(out.facebook, temp);
      break;
    case 3:
      strcpy(out.twitter, temp);
      break;
    case 4:
      strcpy(out.city, temp);
      break;
    case 5:
      strcpy(out.drink, temp);
      break;
    case 6:
      strcpy(out.phone, temp);
      break;
    default:
      break;
    }
    }
  va_end(vl);

  return out;
}

void printPerson(struct TPersonData data)
{
  printf ("Name: %s\n", data.name);
  printf ("Blog: %s\n", data.blog);
  printf ("Facebook: %s\n", data.facebook);
  printf ("Twitter: %s\n", data.twitter);
  printf ("City: %s\n", data.city);
  printf ("Drink: %s\n", data.drink);
  printf ("Phone: %s\n", data.phone);
  printf ("\n\n");
}

int main(int argc, char *argv[])
{
  struct TPersonData p = new_person("Gaspar Fernandez", "Binary Prose", NULL);
  printPerson(p);
 
  p = new_person("John Doe", "JD Blog", "http://facebook.com/johndoe", "@johndoe", "New York", NULL);
  printPerson(p);
  return EXIT_SUCCESS;
}

It’s important not to forget the NULL after all arguments are passed, or we will see some unexpected behavior in runtime.

Photo: Robyn Petrovich (Flickr) CC-by

Top