Variablen Frage bezüglich Programmierverständnis

quest1on

Mitglied
Guten Tag liebe Boarder,

Ich bin ein kompletter Neuling und versuche zurzeit Empathie aufzubauen für die Programmiersprache Java.

Ich habe folgende Aufgabe zu bewältigen(allgemein):

Einen Kalender programmieren mit gegebenen Algorithmen und festgelegtem Ausgabeschema.

Erwartete Ausgabe:

Java:
******************* Mai 2016 *******************
    So  Mo  Di  Mi  Do  Fr  Sa
    01    02    03    04    05    06    07
    08    09    10    11    12    13    14   
    15    16    17    18    19    20    21   
    22    23    24    25    26    27    28   
    29    30    31

Kopfzeile als String, Wochentagskürzel und immer 2-stellige Tagesnummern habe ich bis jetzt erfolgreich schreiben können.

Der Kalender ist im amerikanischen Stil und der Sonntag des Mai 2016 ist tatsächlich der 1. des Monats. Jedoch ist es daraufhin abgeleitet im Monat Juni nicht ein Sonntag, sondern ein Mittwoch.
Ich müsste mit den unten angegebenen Algorithmen ein kleine Erweiterung in meinen bisherigen Code einbauen, damit der Scanner einwandfrei läuft und die Ausgabe richtig abwickelt.
Kurz gefasst: 1. Wochenzeile im Juni 2016 soll "So", "Mo" und "Di" leer sein und der Mittwoch = "01"

Bis jetzt konnte ich gedanklich nur fassen, dass höchstwahrscheinlich einen Variable deklariert werden muss, der den 1. Tag im Monat berechnet und eine for/while Schleife die Leerstellen lässt, bis der richtige Tag im Monat angekommen ist und erst dann mit 01, 02, 03 - 28(29,30,31) auffüllt.


Mein bisher getipptes:
Java:
private String getMonatsblatt(int jahr, int monat){
           
        String pattern="###,#00";
        DecimalFormat asdf = new DecimalFormat(pattern);
       
        if(kalfunk.istSchaltjahr(jahr)) {
        for(int y=0;y < kalfunk.monatslaenge[1][monat];) {
            if(y % 7 == 0) {
                System.out.println();
            }
            System.out.print(asdf.format(y=y+1)+" " );
            System.out.print(" ");
        }
        return " ";
        } else {
            for(int y=0;y < kalfunk.monatslaenge[0][monat];) {
                if(y % 7 == 0) {
                    System.out.println();
                }
                System.out.print(asdf.format(y=y+1) );
                System.out.print(" ");
            }
            return " ";
        }

Gegebene Algorithmen:

Java:
/**
 =========================================================================
 * Funktion:    tagesnummer(int tag, int monat, int jahr)
 * Parameter:    tag (long)        : Tag
 *                monat (long)     : Monat
 *                jahr (long)        : Jahr
 * Rueckgabe:    n (int)      : Tagesnummer rel. zum Jahresanfang
 *                            (1=1.1.,2=2.1.,...365/366=31.12)
 * Beschreibung: Algorithmus von Robertson
 * =========================================================================
 */
 int tagesnummer(int tag, int monat, int jahr)
 {
   int d, e;
   d = (monat+10)/13;
   e = tag + (611*(monat+2))/20 - 2*d - 91;
   return (e + schaltjahr (jahr) * d );
 }


/**
 =========================================================================
 * Funktion:    wochentag_im_jahr(int jahr, int n)
 * Parameter:    jahr (long)    : Jahr
 *                n (int)        : Tagesnummer rel. zum Jahresanfang
 *                             (1=1.1.,2=2.1.,...365/366=31.12)
 * Rueckgabe:    (int) : Wochentag (0=So, 1=Mo,..., 6=Sa)
 * Beschreibung: Algorithmus von Zeller
 * =========================================================================
 */
 int wochentag_im_jahr(int jahr, int n)
 {
   int j, c;
   j = (jahr-1) % 100;
   c = (jahr-1) / 100;
   return (28+j+n+(j/4)+(c/4)+5*c) % 7;
 }

Vielen Dank im Vorhinein für eure Unterstützung.
lg
 
Du bräuchtest im Prinzip eine Methode, die dir verrät, welcher Tag nun dein erster im momentanen Monat ist, sonst weiß du ja nicht, welcher Tag den ersten Eintrag kriegt. Oder hast du so was schon?
 
Im Prinzip musst du nur abfragen, falls int wochentag_im_jahr(int jahr, int n) aufgerufen wird und n derartig gewählt wird, so dass es immer auf den ersten eine Montags steht, welcher Wert rauskommt und berechnen. Ist das Ergebnis 1, dann addierst du ein Mal " ", wenn 2 rauskommst, machst du das zwei mal.. so müsste die Struktur So - Sa immer gleich bleiben.

So?
Code:
private String getMonatsblatt(int jahr, int monat){
       
        String pattern="###,#00";
        DecimalFormat asdf = new DecimalFormat(pattern);
       for(int t=0; t<wochentag_im_jahr(jahr, tagesnummer(1, monat, jahr));t++){
System.out.print(" ");
}
        if(kalfunk.istSchaltjahr(jahr)) {
        for(int y=0;y < kalfunk.monatslaenge[1][monat];) {
            if(y % 7 == 0) {
                System.out.println();
            }
            System.out.print(asdf.format(y=y+1)+" " );
            System.out.print(" ");
        }
        return " ";
        } else {
            for(int y=0;y < kalfunk.monatslaenge[0][monat];) {
                if(y % 7 == 0) {
                    System.out.println();
                }
                System.out.print(asdf.format(y=y+1) );
                System.out.print(" ");
            }
            return " ";
        }

Ich kann derzeit leider nicht testen.
 
Zuletzt bearbeitet:
ich habe es gerade getestet und der Sonntag ist immernoch der erste Tag in allen Monaten.

Könntest du mir erklären, was du überhaupt gemacht hast? Ich blicke nicht ganz dahinter leider
 
Ich hab nur diese Zeile

Code:
for(int t=0; t<wochentag_im_jahr(jahr, tagesnummer(1, monat, jahr));t++){
System.out.print(" ");
}

eingefügt. Ich hole mir den ersten Tag eines Monats raus mit tagesnummer(1, monat, jahr) und gelange dann mit wochentag_im_jahr an den Namen des Strings in int (0=Sonntag, 1 = Montag, ...).
Wenn da jetzt 1 rauskommt, also Montag, schiebe ich Montag einfach um eins nach rechts, denn Sonntag steht vor Montag, aber Sonntag ist leer.
Wenn 2 da steht, ist Dienstag der erste Tag und Sonntag & Montag leer, also schiebe ich zwei mal nach rechts bzw. schreibe zwei mal gar nichts.
 
ansich klingt das sinnvoll, aber in keinem monat wird was verschoben, der compiler zeigt auch keine Fehler an. Ich würde fast tippen, dass die Algorithmen falsch benutzt werden, oder?
 
also Sonntag ist immer als wochentag der erste in der kalenderdarstellung. Jedoch ist im Monat Juni 2016 der erste Tag des Monats ein Freitag. Wenn ich es mit dem 5canner durchspiele, zeigt er folgendes:
Bitte geben Sie das Jahr ein:2016
Bitte geben Sie den Monat ein07
*******************Juli 2016*******************
So Mo Di Mi Do Fr Sa
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

hier der komplette Code:

Java:
package kalender;
import java.text.DecimalFormat;
import java.util.Scanner;

public class Kalender {

    Scanner scan = new Scanner(System.in);
    KalenderFunktionen kalfunk = new KalenderFunktionen();
  
  
    /**
    * Beschreibung: Erzeugt ein Monatsblatt des Jahreskalenders
    * und gibt das Monatsblatt in Stringform zurück.
    * Das Monatsblatt wird in einem String mit Zeilenumbrüchen abgelegt.
    * Das Monatsblatt enthält immer die Kopfzeile für den entsprechenden Monat.
    * Beispiel:
    *
    ******************* Mai 2016 *******************
    So  Mo  Di  Mi  Do  Fr  Sa
    01    02    03    04    05    06    07
    08    09    10    11    12    13    14  
    15    16    17    18    19    20    21  
    22    23    24    25    26    27    28  
    29    30    31
    *
    *@param jahr - das Jahr zum Monat
    *@param monat - der Monat, der angezeigt werden soll
    *@return String - der zusammengebastelte String
    */
//    private String getMonatsblatt(int jahr, int monat){
//          
//        String pattern="###,#00";
//        DecimalFormat asdf = new DecimalFormat(pattern);
//      
//        if(kalfunk.istSchaltjahr(jahr)) {
//        for(int y=0;y < kalfunk.monatslaenge[1][monat];) {
//            if(y % 7 == 0) {
//                System.out.println();
//            }
//            System.out.print(asdf.format(y=y+1)+" " );
//            System.out.print(" ");
//        }
//        return " ";
//        } else {
//            for(int y=0;y < kalfunk.monatslaenge[0][monat];) {
//                if(y % 7 == 0) {
//                    System.out.println();
//                }
//                System.out.print(asdf.format(y=y+1) );
//                System.out.print(" ");
//            }
//            return " ";
//        }
      
  
      
      
      
    private String getMonatsblatt(int jahr, int monat){
        
        String pattern="###,#00";
        DecimalFormat asdf = new DecimalFormat(pattern);
       for(int t=0; t<kalfunk.wochentag_im_jahr(jahr, kalfunk.tagesnummer(1, monat, jahr));t++){
System.out.print(" ");
}
        if(kalfunk.istSchaltjahr(jahr)) {
        for(int y=0;y < kalfunk.monatslaenge[1][monat];) {
            if(y % 7 == 0) {
                System.out.println();
            }
            System.out.print(asdf.format(y=y+1)+" " );
            System.out.print(" ");
        }
        return " ";
        } else {
            for(int y=0;y < kalfunk.monatslaenge[0][monat];) {
                if(y % 7 == 0) {
                    System.out.println();
                }
                System.out.print(asdf.format(y=y+1) );
                System.out.print(" ");
            }
            return " ";
        }
        }
    /**
    * Methode, um die Kopfzeile eines Monatsblattes in Stringform zurückzugeben.
    * Dieses erfordert die Übergabe des Monats und des Jahres als Integer
    * und liefert die Kopfzeile komplett als String zurück.
    * @param jahr - das Jahr zum Monat
    * @param monat - der Monat, der angezeigt werden soll
    * @return liefert die Kopfzeile komplett als String zurück
    *      Beispiel:
    ******************* Mai 2016 *******************
    So    Mo    Di    Mi    Do    Fr    Sa
    *
    */
    private String getKopfzeileMonatsblatt(int jahr, int monat) {
      
        String Kopfzeile = "*******************"+kalfunk.monatsname[monat]+ " " +jahr+"******************* \r";
        System.out.print(Kopfzeile);
        for(int x = 0; x < 7; x++){
            System.out.print(kalfunk.wochentagkurz[x]+ "  ");
        }
            return Kopfzeile;
        }
    /**
    * Methode zur Ausgabe eines Monatsblattes auf der Konsole
    *
    * @param jahr - das Jahr zum Monat
    * @param monat - der Monat, der angezeigt werden soll
    */
    public void zeigeMonat(int jahr, int monat) {
  
        String Kopfzeile = "*******************"+kalfunk.monatsname[monat]+ " " +jahr+"******************* \r";
    System.out.println(Kopfzeile);

    String pattern="###,#00";
    DecimalFormat form = new DecimalFormat(pattern);
    for(int y=0;y < kalfunk.monatslaenge[1][monat];) {
        if(y % 7 == 0) {
            System.out.println();
        }
        System.out.print(form.format(y=y+1) );
        System.out.print(" ");
      
      
        if(kalfunk.istSchaltjahr(jahr)) {
      
    }}
    }
    /**
    * Methode zur Ausgabe aller Monatblätter eines Jahres auf der Konsole
    * @param jahr - das Jahr, das angezeigt werden soll.
    */
//    public void zeigeJahr(int jahr)
  
    /**
    * Die Methode liest eine Monatszahl ein,
    * evaluiert diese Zahl auf den gültigen Bereich[1,..,12]
    * und gibt die eingelesene und überprüfte Monatszahl zurück.
    * Wenn der Benutzer keine gültige Monatszahl eingibt, verbleibt
    * das Programm in der Einlese-Schleife.
    * @return in - der eingelesene Monat
    */
    private int liesMonat(){
        System.out.print("Bitte geben Sie den Monat ein");
        int monat = scan.nextInt();
      
        while(monat > 13 || monat < 1) {
            System.out.print("Bitte wählen Sie einen Wert zwischen 1 und 12");
            monat = scan.nextInt();
            }
            return monat;  
        }
  
  
    /**
    * Die Methode liest eine Jahreszahl ein,
    * evaluiert diese Zahl auf die gültigen Ziffern
    * und gibt die eingelesene und überprüfte Jahreszahl zurück.
    * Wenn der Benutzer keine gültige Jahresangabe macht, verbleibt
    * das Programm in der Einlese Schleife.
    * @return int - das eingelesene Jahr
    */
    private int liesJahr(){
      
        System.out.print("Bitte geben Sie das Jahr ein:");
        int jahr = scan.nextInt();
      
        while(jahr > 2020 || jahr < 2000) {
            System.out.print("Bitte ein Jahr zwischen 2000 und 2020 eingeben");
            jahr = scan.nextInt();
            }
            return jahr;
        }

    /**
    * stellt das Auswahlmenü dar und liest die Benutzerauswahl ein.
    * die Benutzerauswahl wird evaluiert auf Gültigkeit.
    * Wenn der Benutzer keine gültige Eingabe macht, verbleibt
    * das Programm in der Einlese-Schleife
    */
  
    public void auswahlMenue() {
        int jahr = liesJahr();
        int monat = liesMonat();
        getKopfzeileMonatsblatt(jahr, monat);
        getMonatsblatt(jahr,monat);
    }
      
}
 
Zuletzt bearbeitet:
Entschuldige, hier ist sie:

Java:
package kalender;

/**
* Beschreibung: Algorithmen für Kalenderfunktionen. Insbesondere 5chaltjahrregel, Tagesnummer
*
* Diese Algorithmen sind zusammengetragen aus verschiedenen Quellen.
*
* Bitte verändern Sie diese Datei nicht!
* Falls Sie zusätzliche Funktionen benötigen, legen Sie eine eigene java-Datei an!
*
* @author bannert
*/

public class KalenderFunktionen
{

    final String[] monatsname =
    { null, "Januar", "Februar", "Maerz", "April", "Mai", "Juni", "Juli",
            "August", "September", "Oktober", "November", "Dezember" };
  
    final String[] wochentagkurz =
    { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" };
  
    final int[][] monatslaenge =  {
    { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
    { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
                                };
  
/**
=========================================================================
* Funktion:    istSchaltjahr( int jahr )
* Parameter:    jahr (int)    :    das Jahr, das auf Schaltjahr ueberprueft wird
* Rueckgabe:    (boolean)     :     true, wenn das Jahr ein Schaltjahr ist
*                :     false,  wenn das Jahr nicht Schaltjahr ist
* Beschreibung: jedes 4.te Jahr ist Schaltjahr,
* (wenn sich das Jahr durch 4 ohne Rest teilen laesst, ist es Schaltjahr )
* Ausnahme davon jedes 100.te Jahr ist kein Schaltjahr
* (wenn sich das Jahr durch 100 ohne Rest teilen laesst, ist es kein Schaltjahr)
* Ausnahme davon jedes 400.ter Jahr    ist wieder Schaltjahr
* (wenn sich das Jahr durch 400 ohne Rest teilen laesst, ist es Schaltjahr)
* =========================================================================
*/
boolean istSchaltjahr(int jahr)
{
    return ((jahr%4 == 0 )&&((jahr%100 != 0 )||( jahr%400 == 0 )));
}


/**
=========================================================================
* Funktion:    schaltjahr(int jahr)
* Parameter:    jahr (int)    :    das Jahr, das auf Schaltjahr ueberprueft wird
* Rueckgabe:    (int)     :     1 = true, wenn das Jahr ein Schaltjahr ist
*            :     0 = false,  wenn das Jahr nicht Schaltjahr ist
* Beschreibung: siehe --> istSchaltjahr(long jahr)
* =========================================================================
*/
int schaltjahr(int jahr)
{
    if(istSchaltjahr(jahr)) return 1;
    else return 0;
}


/**
=========================================================================
* Funktion:    tagesnummer(int tag, int monat, int jahr)
* Parameter:    tag (long)        : Tag
*                monat (long)     : Monat
*                jahr (long)        : Jahr
* Rueckgabe:    n (int)      : Tagesnummer rel. zum Jahresanfang
*                            (1=1.1.,2=2.1.,...365/366=31.12)
* Beschreibung: Algorithmus von Robertson
* =========================================================================
*/
int tagesnummer(int tag, int monat, int jahr)
{
   int d, e;
   d = (monat+10)/13;
   e = tag + (611*(monat+2))/20 - 2*d - 91;
   return (e + schaltjahr (jahr) * d );
}


/**
=========================================================================
* Funktion:    wochentag_im_jahr(int jahr, int n)
* Parameter:    jahr (long)    : Jahr
*                n (int)        : Tagesnummer rel. zum Jahresanfang
*                             (1=1.1.,2=2.1.,...365/366=31.12)
* Rueckgabe:    (int) : Wochentag (0=So, 1=Mo,..., 6=Sa)
* Beschreibung: Algorithmus von Zeller
* =========================================================================
*/
int wochentag_im_jahr(int jahr, int n)
{
   int j, c;
   j = (jahr-1) % 100;
   c = (jahr-1) / 100;
   return (28+j+n+(j/4)+(c/4)+5*c) % 7;
}



} // end of class
 
Zuletzt bearbeitet:
Probiere mal das (c&p):
Code:
private String getMonatsblatt(int jahr, int monat) {

        int day = 0;
        String pattern = "###,#00";
        DecimalFormat asdf = new DecimalFormat(pattern);
        int firstDay = kalfunk.wochentag_im_jahr(jahr, kalfunk.tagesnummer(1, monat, jahr));
        for (int t = 0; t < firstDay; t++) {
            System.out.print(" ");
        }
        if (kalfunk.istSchaltjahr(jahr)) {
            for (int y = 0; y < kalfunk.monatslaenge[1][monat]; y++) {
                if (y % 7 == 0) {
                    System.out.println();
                }
                if (y == 0) {
                    for (int t = 0; t < firstDay; t++) {
                        System.out.print(" ");
                        System.out.print(" ");
                        System.out.print(" ");
                        System.out.print(" ");

                        y++;
                    }

                }
                System.out.print(asdf.format(day = day + 1) + " ");
                System.out.print(" ");
            }
            return " ";
        } else {
            for (int y = 0; y < kalfunk.monatslaenge[0][monat];) {
                if (y % 7 == 0) {
                    System.out.println();
                }
                if (y == 0) {
                    for (int t = 0; t < firstDay; t++) {
                        System.out.print(" ");
                        System.out.print(" ");
                        System.out.print(" ");
                        System.out.print(" ");

                        y++;
                    }

                }
                System.out.print(asdf.format(day = day + 1) + " ");
                System.out.print(" ");
            }
            return " ";
        }
    }


Ich habe jetzt erstmal den if Zweig if (kalfunk.istSchaltjahr(jahr)) bearbeitet.

Erklärung: Falls y=0, füge so viele leere Stellen ein bis der erste Tag kommt.
Ist firstDay = 0, dann ist Sonntag der erste Tag, falls firstDay = 1, ist Montag der erste Tag, etc.
Zähle y danach hoch, damit man jedes mal, wenn man etwas "Leeres" einfügt, ein mal weniger einen Tag hinzufügt, sonst hat man am Schluss Tage, die nicht mehr auf Wochentage abgebildet werden. (zum Testen kannst du mal y++ rausnehmen).
Dann war das Problem mit y = y + 1 in deiner Ausgabe. Wird nun was übersprungen, startet dein Monat nicht mit 01, sondern eventuell mit 03 oder 04, also so oft, wie übersprungen wird, also brauchst du eine extra Variable.
 
Zuletzt bearbeitet:
Danke dir vielmals, klappt bis jetzt(^^) einwandfrei.

Könntest du mir noch netterweise erklären, was du genau gemacht hast?
Ich würde das gerne als kompletter Neuling gerne verstehen 🙂
 
Eine kleine Rückmeldung nochmal:

Ich habe gemerkt, dass alles einwandfrei funktioniert, außer folgendes:

Java:
Bitte geben Sie das Jahr ein:2016
Bitte geben Sie den Monat ein12
*******************Dezember 2016******************* 
So  Mo  Di  Mi  Do  Fr  Sa      
                01  02  03  
04  05  06  07  08  09  10  
11  12  13  14  15  16  17  
18  19  20  21  22  23  24  
25  26  27

es fehlen die letzten Tage, Dezember muss bis 31 hochgezählt werden

Meine Vermutung: Das Programm zählt die gesamte Monatslänge hoch, von 1-31 z.B. Gibt aber nicht bis 31 aus, da es jetzt frei stellen gibt. Undzwar zählt er 4 Leerstellen und dann nur noch 27 hoch(insgesamt 31)
 
Wenn ich einen Vorschlag machen darf:

Ich würde den int t übernehmen(abspeichern) und ihn in diese For Schleife einbauen:

for (int y = 0; y < kalfunk.monatslaenge[1][monat]+t ; y++)

Also Entdprodukt:

for (int t = 0; t < firstDay; t++) {
System.out.print(" ");
return t;
}
if (kalfunk.istSchaltjahr(jahr)) {
for (int y = 0; y < kalfunk.monatslaenge[1][monat]+t ; y++)

Das Problem ist nur, dass ich einen Compiler Fehler bekomme:
Type missmatch: cannot convert from int to string

lg
 
Lass mal das return t weg. Du befindest dich ja in einer Methode, die einen String zurück gibt.
Mit return t gibst du aber einen int zurück und deswegen meckert er.

Wenn du das machst, wird es dir so nicht viel bringen, wegen der Abfrage
Code:
if(y%7==0)
{
System.out.println();
}
Denn vor dieser Abfrage befindest du dich ja noch in der Zeile wo die Wochentage-Strings stehen.
Probiere mal:
Code:
if(y%7==0 && y>0)
{
System.out.println();
}
 
Aso mein Fehler. Diese for-Schleife mit t kannst du weglassen.

Code:
private String getMonatsblatt(int jahr, int monat) {

        int day = 0;
        String pattern = "###,#00";
        DecimalFormat asdf = new DecimalFormat(pattern);
        int firstDay = kalfunk.wochentag_im_jahr(jahr, kalfunk.tagesnummer(1, monat, jahr));
        if (kalfunk.istSchaltjahr(jahr)) {
            for (int y = 0; y < kalfunk.monatslaenge[1][monat] + firstDay; y++) {
                if (y % 7 == 0) {
                    System.out.println();
                }
                if (y == 0) {
                    for (int t = 0; t < firstDay; t++) {
                        System.out.print(" ");
                        System.out.print(" ");
                        System.out.print(" ");
                        System.out.print(" ");

                        y++;
                    }

                }
                System.out.print(asdf.format(day = day + 1) + " ");
                System.out.print(" ");
            }
            return " ";
        } else {
            for (int y = 0; y < kalfunk.monatslaenge[0][monat] + firstDay;) {
                if (y % 7 == 0) {
                    System.out.println();
                }
                if (y == 0) {
                    for (int t = 0; t < firstDay; t++) {
                        System.out.print(" ");
                        System.out.print(" ");
                        System.out.print(" ");
                        System.out.print(" ");

                        y++;
                    }

                }
                System.out.print(asdf.format(day = day + 1) + " ");
                System.out.print(" ");
            }
            return " ";
        }
    }
 
hatte deine neue antwort nicht gesehen, funktioniert jetzt super

Was war denn dein Fehler?
sry hab dir ziemlich viel arbeit gemacht, ich lerne noch^^
 
Es gab keinen Fehler. Die erste for-Schleife war sinnlos, denn sie hat in der ersten Zeile, in der die Wochentage (So-Sa) stehen, Leerzeichen eingefügt.
Die eigentliche Logik des Aufbaus fängt erst nach
Code:
if(y%7==0)
{
System.out.println();
}
an, da man erst dort in die erste Reihe der Zahlen gelangt.

Keine Bange, jeder fängt mal klein an 🙂
 

Zurück
Oben