C++ zeigt in der Ausgabe nichts an

Gast #4053672
Lesenswert?

Nabend,
ich möchte ein Programm schreiben, in dem ich ermittle, wie oft der 
Montag der 1.,2.,3.,.... Dienstag der1.,2.,... usw. war.
1
#include <stdio.h>
2
#include <time.h>
3

4

5
int main(void) {
6
    char *wday[] = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "???" };
7
    struct tm ts;
8
    //int auswertung[7][31];
9
    int year, month, day;
10
 
11
  for(year=2000; year<=2015; year++){
12
    for(month=1; month<=12; month++){
13
      for(day=1; day<=31; day++){
14
        ts.tm_year = year - 1900;
15
        ts.tm_mon  = month - 1;
16
          ts.tm_mday = day;
17
          if ( mktime(&ts) == -1 )
18
            ts.tm_wday = 7;
19
            if(wday[ts.tm_wday]!="???"){
20
              printf("%s, %d, %d\n",wday[ts.tm_wday],ts.tm_wday,day);
21
          }
22
          
23
      }
24
    }
25
  }
26
  return 0;
27
}

bisher lasse ich mir die Tage und Datums in der Konsole ausgeben.
Um mein eigentliches Vorhaben zu machen, wollte ich eine Matrix 
schreiben (7x32)- Damit habe ich jede kombination gegeben und kann in 
jedem Feld den wert erhöhen.

das Problem ist, sobald ich die Zeile
1
int auswertung[7][31];
auskommentiere, wird mir in der Konsole nichts mehr angezeigt.
Woran liegt das? Das macht für mich keinen sinn.

Stephan
Gast #4053711
Lesenswert?

> char* ist aber kein String sondern ein Array und Arrays kann man (so)
> nicht vergleichen.

Nö, char* ist ein Zeiger, und der Compiler warnt zu Recht davor, 
selbigen Zeiger mit der ∗Adresse∗ eines String-Literals zu vergleichen.
Moderator #4053717
Lesenswert?

Stephan schrieb:
> Habe es trotzdem geändert. Dennoch bleibt das Problem das selbe.

Auch den Elemente tm_hour, tm_min und tm_sec in ts solltest du sinnvolle
Werte zuweisen (im einfachsten Fall 0). Lediglich tm_wday, tm_yday und
tm_isdst kannst du uninitialisiert lassen, da sie von mktime berechnet
werden.

Edit:

tm_isdst musst du ebenfalls initialisieren (s. Man-Page von mktime).
Gast #4053826
Lesenswert?

Schreibe es jetzt in eine textdatei. das funktioniert auch soweit. Das 
Problem was ich jetzt habe, dass ich nicht weiss, wie ich überprüfen 
kann, ob der Tag überhaupt existiert hat. Momentan spuckt er mir aus, 
dass der 29.Februar2014 ein Samstag war und zählt diesen mit. 
(30.Februar2014->Sonntag, 31.Februar2014->Montag).

kann ich auch irgendwie kontrollieren, ob dieser Tag überhaupt existiert 
hat?
1
#include <fstream>
2
#include <iostream>
3
#include <string>
4
#include <stdio.h>
5
#include <time.h>
6

7
using namespace std;
8

9
#define numwdays 7
10
#define numdays 31
11

12
int main(void) {
13
    char *wday[] = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
14
    int x=0;
15
    struct tm ts;
16
    int auswertung[numdays][numwdays];
17
    for(int k=0; k<numdays; k++){
18
      for(int l=0; l<numwdays; l++){
19
        auswertung[k][l] = 0;
20
    }
21
  }
22
  ts.tm_hour = 0;
23
    ts.tm_min  = 0;
24
    ts.tm_sec  = 1;
25
    ts.tm_isdst = -1;
26
    
27
  for(int year=2014; year<2015; year++){
28
    for(int month=2; month<=2; month++){
29
      for(int day=1; day<=31; day++){
30
        ts.tm_year = year-1900;
31
        ts.tm_mon  = month-1;
32
          ts.tm_mday = day;
33
          
34
          if ( mktime(&ts) == -1 ){
35
            ts.tm_wday = 7;
36
        }
37
        printf("Dieser Tag ist ein %s\n", wday[ts.tm_wday]);    
38
        
39
          if(ts.tm_wday>=0 && ts.tm_wday<=6){
40
            auswertung[ts.tm_mday-1][ts.tm_wday] = auswertung[ts.tm_mday-1][ts.tm_wday] + 1;
41
            x = x + 1;
42
          }
43
        }
44
    }
45
  }
46
  
47
  ofstream f("text.txt");
48
  for(int m=0;  m<numdays; m++){
49
    for(int n=0; n<numwdays; n++){
50
      //printf("%-9d", auswertung[m][n]);
51
      f <<  auswertung[m][n];
52
      f << "   ";
53
    }
54
    f << ("\n");
55
  }
56
  f << x;
57
  f.close();
58
  return 0;
59
}
#4053979
Lesenswert?

Stephan schrieb:
> kann ich auch irgendwie kontrollieren, ob dieser Tag überhaupt existiert
> hat?

Vergleiche nach dem mktime,  ob die Werte in ts dieselben sind, die du 
vorher rein geschrieben hast.

Zu deinem ersten Problem.
Es gibt in C eine feste Adresse, die man für ungültige Adressen 
verwendet: NULL
1
    char *wday[] = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", NULL};
2
...
3
            if(wday[ts.tm_wday] != NULL){
Allerdings ist in diesem Fall die Version mit dem Vergleich von 
ts.tm_wday < 7 besser.

Und das
1
printf("Dieser Tag ist ein %s\n", wday[ts.tm_wday]);
 muss mit in das nachfolgende if rein.
Gast #4054000
Lesenswert?

mhh,
habe es jetzt so gemacht, dass ich mir die Tage in einem Monat aus einer 
Funktion geben lasse und die for-Schleife für die Tage nur bis dahin 
laufen lass.
1
#include <fstream>
2
#include <iostream>
3
#include <string>
4
#include <stdio.h>
5
#include <time.h>
6

7
using namespace std;
8

9
#define numwdays 7
10
#define numdays 31
11

12

13
int getDaysInMonth(int month, int year);
14

15

16

17
int main(void) {
18
    char *wday[] = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", NULL};
19
    int x=0;
20
    int daysInMonth=0;
21
    struct tm ts;
22
    int auswertung[numdays][numwdays];
23
    for(int k=0; k<numdays; k++){
24
      for(int l=0; l<numwdays; l++){
25
        auswertung[k][l] = 0;
26
    }
27
  }
28
  ts.tm_hour = 0;
29
    ts.tm_min  = 0;
30
    ts.tm_sec  = 1;
31
    ts.tm_isdst = -1;
32
    
33
  for(int year=2015; year<=2015; year++){
34
    for(int month=2; month<=2; month++){
35
      daysInMonth = getDaysInMonth(month, year);
36
      for(int day=1; day<=daysInMonth; day++){
37
        ts.tm_year = year-1900;
38
        ts.tm_mon  = month-1;
39
          ts.tm_mday = day;
40
          
41
          if (mktime(&ts) == -1 ){  
42
            ts.tm_wday = 7;
43
        }  
44
          if(ts.tm_wday>=0 && ts.tm_wday<=6){
45
            printf("Dieser Tag ist ein %s\n", wday[ts.tm_wday]);  
46
            auswertung[ts.tm_mday-1][ts.tm_wday] = auswertung[ts.tm_mday-1][ts.tm_wday] + 1;
47
            x = x + 1;
48
          }
49
        }
50
    }
51
  }  
52
  ofstream f("text.txt");
53
  for(int m=0;  m<numdays; m++){
54
    for(int n=0; n<numwdays; n++){
55
      f <<  auswertung[m][n];
56
      f << "   ";
57
    }
58
    f << ("\n");
59
  }
60
  printf("%d",x);
61
  f << x;
62
  f.close();
63
  return 0;
64
}
65

66

67
bool leapyear(int year){
68
  if ((year % 400) == 0)
69
    return true;
70
  else if ((year % 100) == 0)
71
    return false;
72
  else if ((year % 4) == 0)
73
    return true;
74
  return false;
75
}  
76

77
int getDaysInMonth(int month, int year){
78
  //                     ungült,Jan,Feb,Mrz,Apr,Mai,Jun,Jul,Aug,Sep,Okt,Nov,Dez
79
  int arrDaysInMonth[13] = {  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
80

81
  if (month == 2){
82
    if (leapyear(year)) return 29;
83
    else return 28;
84
  }
85
  else return arrDaysInMonth[month];
86
}


das mit dem vergleichen hört sich aber besser an, habe ich aber nicht 
hinbekommen. Da muss ich erst noch mal ein bisschen probieren.

aber danke schon mal für eure Hilfe.
#4054003
Lesenswert?

>kann ich auch irgendwie kontrollieren, ob dieser Tag überhaupt existiert
> hat?

Ja, in dem du ermittelst ob das Jahr ein Schaltjahr war (wie man das 
programmiertechnisch macht, das kannst du googlen), in dem Falle gibt es 
halt den 29. Februar - ansonsten nicht.

Gruß J
#4054095
Lesenswert?

Ich würde nur für den ersten Tag mktime nehmen. den Rest dann selber aus 
der Tabelle, bzw. mit Schleifen errechnen.


Meist macht man  arrDaysInMonth ein 2D-Array:
1
int arrDaysInMonth[][13] = { {  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
2
                             {  0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
3
                           };

Und das Post/Preincrement geht nicht nur in Schleifen.
Dann ist das
1
auswertung[ts.tm_mday-1][ts.tm_wday]++;
 auch besser lesbar.
1
auswertung[ts.tm_mday-1][ts.tm_wday] += 1;
 geht auch.


Und wenn du Arrays initialisierst, werden die nicht aufgeführten 
Elemente mit 0 besetzt
1
int auswertung[numdays][numwdays] = {0}; // Alles mit 0 besetzt
Sonst ist memset dein Freund.
Gast #4054113
Lesenswert?

Was soll den jetzt dieses Gemisch aus C und C++? Das macht es auch nicht 
besser. Ebensowenig irgendwelche besch... Code dranzukleben.

Oben wurde es schon mal erwähnt: HANDBUCH LESEN!


> The mktime() function modifies the fields of the tm structure as follows:
> tm_wday and tm_yday are set to values determined from the contents of the
> other fields; if structure members are outside their valid interval, they
> will be normalized (so that, for example, 40 October is changed into 9
> November); tm_isdst is set (regardless of its initial value) to a
> positive value or to 0, respectively, to indicate whether DST is or is
> not in effect at the specified time. Calling mktime() also sets the
> external variable tzname with information about the current timezone.

D.h. hat mktime() den Tag verändert, so gibt es das Datum nicht -> 
Ergebnis wegschmeißen.

Einfachster Test, wenn es nur darum geht den 29. (Schaltjahre), 30. und 
31. eines Monats in den Griff zu bekommen:
1
...
2
ts.tm_mday = day;
3
if((mktime(&ts) == -1) || (ts.tm_mday != day)){  
4
    // Den Tag gibt es nicht
5
}
#4054142
Lesenswert?

Jay schrieb:

> Oben wurde es schon mal erwähnt: HANDBUCH LESEN!
>
>> The mktime() function modifies the fields of the tm structure as follows:
>> tm_wday and tm_yday are set to values determined from the contents of the
>> other fields; if structure members are outside their valid interval, they
>> will be normalized (so that, for example, 40 October is changed into 9
>> November);
>
> D.h. hat mktime() den Tag verändert, so gibt es das Datum nicht ->
> Ergebnis wegschmeißen.

Nein, das heisst, eine einfache Schleife genügt:
1
heute = 1. Jan. 2000
2
WHILE heute != 1. Jan 2016
3
  wochentag = wochentag von heute
4
  tag = monatstag von heute
5
  trage (tag, wochentag) in resultat ein
6
  heute = heute + 1
7
  benutze mktime um heute zu normalisieren
8
END WHILE
9

10
zun schluss resultattabelle ausgeben

und damit sind alle Vorrichtungen um Schaltjahre und 28-, 29-, 30 oder 
31-Tagige Monate abzufangen hinfällig, weil mktime das alles 
übernimmt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren