Digitaluhr, Hilfe !

Hallo folgende Aufgabenstellung habe ich erhalten, ich muss sagen bin eine Anfängerin und überfordert. Meine bisherige Bearbeitung führt einfach zu nicht, daher bitte ich um Lösungsvorschläge, Danke im vorraus :).

Programmieren Sie eine Digitaluhr, die Stunden, Minuten, Sekunden und Zehntelsekunden wie folgt anzeigt: h:mm:ss,z Verwenden Sie vier Variablen h, m, s und z für die Werte. Beim Programmstart soll die Uhr 0:00:00,0 anzeigen und dann jede Zehntelsekunde aktualisiert werden. Um eine Zehntelsekunde verstreichen zu lassen, rufen Sie die folgende Anweisung auf: Thread.sleep(100);. Die Uhr soll endlos laufen. Zum Stoppen des Programms verwenden Sie den roten Stopp‐ Button in Eclipse.

Code:
public class DigiUhr {

    public static void main(String[] args) {


        int std = 18;
        int min = 18;
        int sek = 18;
        int ms = 18;


        for (ms=1;ms <= 1000;++ms);

        System.out.println(std + ":" + min + ":" + sek + "," + ms);
        }

    }
 
Du kannst sowohl formatierte Strings als auch Ausgaben erhalten. Probier mal
Java:
// via String:
String s = String.format("%02d", 1); 
System.out.println(s);

// direkt über Ausgabe
System.out.printf("%02d\n", 5); // das \n sorgt für einen Zeilenumbruch wie bei println
 
K

kneitzel

Zerlegen wir das alles doch einmal:
a) Es soll endlos laufen - wie kannst Du etwas bauen, das endlos läuft?
b) alle 100ms sollen die ms um eine Zehntelsekunden erhöht werden (Wie man 100ms warten ist ja vorgegeben.)
c) Ausgabe kannst Du nun bauen - siehe dazu auch den Hinweis von mihe7, wobei die Concatenation auch gehen sollte.
==> Nun kannst Du Dir das Ergebnis ansehen. Was läuft denn nun noch falsch? Was musst Du ändern, damit es korrekt wird? (Das sollte dann gut ersichtlich sein denke ich mal)
 
K

kneitzel

Wobei man hier kein Modulo braucht. Ein if mit == reicht komplett aus, da wir ja die Schrittgröße kennen. Wenn wir die ms immer um 100 erhöhen, dann wissen wir, dass wir dann mal auf 1000 kommen und dann müssen wir was machen.
Sekunden erhöhen wir immer um eins und wenn wir auf 60 kommen, dann machen wir etwas .....
u.s.w.
 
Ich würde sogar sagen, dass man nur Zehntelsekunden zählen muss - zumindest nach Aufgabenstellung :)
 
Java:
import java.util.Calendar;
import java.util.GregorianCalendar;

public class Uhr extends Thread {
	long waitfor = 0;

	@Override
	public void run() {
		try {
			Calendar c = new GregorianCalendar();
			int std = c.get(Calendar.HOUR_OF_DAY);
			int min = c.get(Calendar.MINUTE);
			int sek = c.get(Calendar.SECOND);
			int zs = c.get(Calendar.MILLISECOND) / 100;
			System.out.printf("(%d Millisekunden gewartet)%n%d:%02d:%02d,%d%n", waitfor, std, min, sek, zs);
			waitfor = 100 - System.currentTimeMillis() % 100 + 1;
			Thread.sleep(waitfor);
			run();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		Uhr uhr = new Uhr();
		uhr.start();
	}
}

Aber aufpassen, der Spaß beendet sich nicht einfach so...
 
K

kneitzel

Also ich habe jetzt wieder Probleme, zu verstehen, was Du hier machst @Tobias-nrw:
Die Vorgaben waren doch klar und deutlich und Dein Code hat mit den Vorgaben sehr wenig zu tun.
Es wird kein Calendar benötigt, Thread braucht man nur das sleep(100), das explizit erwähnt wurde ... Ausgabe soll bei 0:00:00,0 anfangen und ansonsten soll da auch nichts angezeigt werden.

Somit dürfte die erwartete Lösung doch eher das Folgende sein:
Java:
public class Uhr {

    public static void main(String[] args) throws InterruptedException {
        int std = 0;
        int min = 0;
        int sek = 0;
        int zs = 0;

        while (true) {
            System.out.printf("%d:%02d:%02d,%d\n", std, min, sek, zs);
            Thread.sleep(100);
            zs++;
            if (zs==10) {
                zs = 0;
                sek++;
                if (sek==60) {
                    sek=0;
                    min++;
                    if (min==60) {
                        min = 0;
                        std++;
                        if (std==24) {
                            std=0;
                        }
                    }
                }
            }
        }
    }
}
Weitere Optimierungen um da die Uhr genau zu halten oder dass die Uhr die korrekte Uhrzeit anzeigt oder sonst irgendwas ist in keiner Weise gefordert.
 
Diese ganzen ifs machen mich ganz wuschig. :) Mit Hilfe von Java 9 VarHandles und Lambdas kann man das noch etwas abstrahieren. Naja... nur, dass man hierfür Instanzvariablen benötigt... aber egal:
Java:
import static java.lang.invoke.MethodHandles.lookup;
import java.lang.invoke.VarHandle;
public class Uhr {
  private static final VarHandle stdH = varHandleTo("std");
  private static final VarHandle minH = varHandleTo("min");
  private static final VarHandle sekH = varHandleTo("sek");
  private static final VarHandle zsH = varHandleTo("zs");
  private static VarHandle varHandleTo(String name) {
    try {
      return lookup().findVarHandle(Uhr.class, name, int.class);
    } catch (NoSuchFieldException | IllegalAccessException e) {
      throw new AssertionError(e);
    }
  }

  private int std;
  private int min;
  private int sek;
  private int zs;

  public void tick() {
    advance(zsH,  10, () -> 
    advance(sekH, 60, () -> 
    advance(minH, 60, () -> 
    advance(stdH, 24, null))));
  }

  private void advance(VarHandle var, int cmp, Runnable next) {
    if ((Integer) var.getAndAdd(this, 1) == cmp - 1) {
      var.set(this, 0);
      if (next != null)
        next.run();
    }
  }

  @Override
  public String toString() {
    return String.format("%d:%02d:%02d,%d", std, min, sek, zs);
  }

  public static void main(String[] args) throws InterruptedException {
    Uhr uhr = new Uhr();
    while (true) {
      System.out.println(uhr);
      Thread.sleep(100);
      uhr.tick();
    }
  }
}
Ja, ich weiß, dass das too much ist, aber mich hat mal interessiert, ob man das Inkrementieren, die Vergleiche und das Reset der einzelnen Zähler wegabstrahieren kann. :)
 
Nur leider gibt es (noch) keine Syntax dafür in der Sprache selbst (wie etwa der Adressoperator '&' in C bzw. Referenzoperator in C++), sondern nur API-Konstrukte wie eben ein VarHandle. Und man kann auch nur Referenzen auf Instanz- und Klassenvariablen haben, nicht auf lokale Methodenvariablen. Sonst wäre "Pass-by-Reference" endlich möglich. :) Naja, zumindest ist jetzt schonmal Pass-by-Reference für Klassen- und Instanzvariablen möglich, wenn auch der Zugriff auf diese Referenz per API erfolgen muss.
Ich hab das Ding aber noch niemals wirklich in Produktivcode benutzt.
 
K

kneitzel

Red mir nicht mit so einem Bullshit dazwischen, was interessieren mich Deine Vorgaben, den kannst Du für Dich behalten... Wenn er eine genaue Uhr haben möchte, kommt er darum nicht herum.
Es sind nicht meine Vorgaben, es sind die Vorgaben des TE. Und der TE wollte eben nicht einfach eine Uhr haben. Wenn Du den Thread gelesen hättest, dann wüsstest Du das auch.

Und statt da meine Aussage als "Bullshit" zu bezeichnen solltest Du einfach einmal den Post vom TE lesen und verstehen.
So ist das, was Du schreibst, einfach nur "Bullshit".
 
K

kneitzel

Wieso nicht einfach ein OO Ansatz?

Das Verhalten einer Stelle ist ja trivial, so dass man da nicht weiter drauf eingehen muss (aktueller Stand, max Stand, erhöhen als Methode).
Und dann per Observer Pattern bekommt die nächste Stelle den Überlauf der vorherigen Stelle.
 
Wenns nur um die ifs geht:
Java:
public class Uhr {

    public static void main(String[] args) throws InterruptedException {
        int std = 0;
        int min = 0;
        int sek = 0;
        int zs = 0;
        int z = 0;

        while (true) {
            System.out.printf("%d:%02d:%02d,%d\n", std, min, sek, zs);
            Thread.sleep(100);
            z++;
            zs = z % 10;
            sek = (z/10) % 60;
            min = (z/600) % 60;
            std = (z/36000) % 24;
            if (std == 0) { z = 0; }
        }
    }
}
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben