Sie sind nicht angemeldet.

[gelöst] Problem mit C Code

Lieber Besucher, herzlich willkommen bei: Ubuntu-Forum & Kubuntu-Forum | www.Ubuntu-Forum.de. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

1

25.01.2013, 18:09

Problem mit C Code

Hallo Leute,

bin dabei ein kleines Übungsprogramm zu erstellen, dass mir in einer CSV Tabelle eine Art Stundenabrechnung erstellt. Die Idee ist, dass eine Person nur an den Tagen Freitag, Samstag und Sonntag arbeitet und das zu "zufälligen" Zeiten. Soweit bin ich momentan schon, hab ein paar Ecken mal auskommentiert, damit ihr sehr wie weit ich bin:

Quellcode

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

FILE *out;
int i,j,N,jahr,tagn,anf,end,days;
int s1;
char heute;
char zeit;
char anf_s, end_s;
char zeitzaehler;
int temp1,temp2,anf1,end1,anf2,end2,zufall1,zufall2;



int main(void)
{
	out=fopen("stundenabrechnung.csv", "w");

	
	printf("Dieses Programm erstellt Ihnen für ein Jahr eine Stundenabrechnung.\n\
	Bitte Jahreszahl eingeben:");
	scanf("i%", &jahr);
	
	fprintf(out,"Stundenabrechnung für das Jahr %i\nDatum;Tag;Von;Bis;Dauer[h];\
	Gesamt[h]\n", jahr);
	
	printf("Was war der erste Tag im Jahr?");
	scanf("d% (Montag=1, Dienstag=2, Mittwoch=3, Donnerstag=4, Freitag=5\
	Samstag=6, Sonntag=7", &s1);
	printf("Wie viele Tage hat dieses Jahr?");
	scanf("%d", &days);
	
	printf("Wann fangen sie frühestens an zu arbeiten? Eingabe bitte\
	nur ganz- oder halbzahlig (z.B. 9.00 Uhr = 9 oder 9.30 Uhr = 9.5)\n");
	scanf("%d", &anf1);
	printf("Wann fangen sie spätestens an zu arbeiten? Eingabe bitte\
	nur ganz- oder halbzahlig (z.B. 9.00 Uhr = 9 oder 9.30 Uhr = 9.5)\n");
	scanf("%d", &end1);
	///Erstelle mir ein kleines Zeitintervall von n*30 Minuten. n=temp1 verwende
	///ich später als obere Grenze bei meiner Zufallszahl.
	temp1=1+(end1-anf1)*2;
           	
	printf("Wann hören sie frühestens auf zu arbeiten? Eingabe bitte nur\
	ganz- oder halbzahlig (z.B. 17.00 Uhr = 17 oder 17.30 Uhr = 17.5)\n");
	scanf("%d", &anf2);
	printf("Wann hören sie spätestens auf zu arbeiten? Eingabe bitte\
	nur ganz- oder halbzahlig (z.B. 17.00 Uhr = 17 oder 17.30 Uhr = 17.5)\n");
	scanf("%d", &end2);
	temp2=1+(end2-anf2)*2;
	
	for(i=1;i<=days;i++)
	{
    	///Die for-Schleife soll so durchlaufen, dass sie alle 365 / 366 Tage
    	///des Jahres durchläuft. Ist der Tag kein FR, SA, SO soll tagn++. 
    	///Ansonsten kommen noch andere Befehle hinzu.
    	if(tagn==5)
    	{
     	///Erstellt mir die zwei Zufallszeit wann ich anfange / aufhöre zu
     	///arbeiten. Allerdings wird diese Funktion garnet erst richtig
     	///ausgeführt, da wohl etwas mit dem Zufallsgenerator nicht stimmt.
     	time();
     	///Soll mir einen String anhand meines doubles anf ausgeben.
     	anf_s=zeitzaehler(anf); 
     	end_s=zeitzaehler(end);
     	heute = FR;
     	fprintf(" ;%s;%s;%s;%d; \n",datum,heute,anf_s,end_s,end-anf);
     	///Kann man eine Berechnung wie hier, "end-anf" einfügen???
     	tagn++;
    	}
    	if(tagn==6)
    	{
     	time();
     	anf_s=zeitzaehler(anf); 
     	end_s=zeitzaehler(end);     	
     	heute = SA;
     	fprintf(" ;%s;%d;%d;%d; \n",datum,heute,anf,end,end-anf);
     	tagn++;
    	}
    	if(tagn==7)
    	{
     	time();
     	anf_s=zeitzaehler(anf); 
     	end_s=zeitzaehler(end);     	
     	heute = SO;
     	fprintf(" ;%s;%d;%d;%d; \n",datum,heute,anf,end,end-anf);
     	tagn=0;
    	}
     	else
     	tagn++;
	}
}

double times()
{         	
	///Gibt mir eine Zufallszahl zwischen 0 und temp1 bzw. temp2 aus.
	srand(time(NULL));
	zufall1 = rand() % temp1 +0;
	srand(time(NULL));
	zufall2 = rand() % temp2 +0;
    	
	///Berechne mir eine "künstliche" Zeit an der ich zu arbeiten beginne.
	anf =anf1*(1+zufall1);
	end =anf2*(1+zufall2);
	///Werden mir die beiden doubles anf und end auch so zur weiteren Berechnung
	///zur Verfügung stehen??
	return anf, end;
}

void zeitzaehler(double res)
{
   	///Ist meine Zeit "voll", dann soll als Uhrzeit dargestellt werden. Z.B.
   	/// temp1 = 9 => string "9:00"
   	if(res%1 == 0)
   	return zeit=("%d:00",res);

   	///Ist meine Zeit "halbvoll", dann soll als Uhrzeit dargestellt werden.
   	///Z.B. temp1 = 9.5 => string "9:30"   	
   	else
   	{
       	res=res-0.5;
       	return zeit=("%d:30",res);
   	}
}


Kann da bitte mal jemand drüber schauen wo der Fehler liegen könnte? Wie gesagt, momentan kann ich es nicht zu 100% kompilieren lassen, eventuell sind noch weitere Fehler drinnen.

Gruß der grillmeister

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »grillmeister« (03.02.2013, 10:55)


.not

User

Beiträge: 762

Registrierungsdatum: 28.07.2011

Derivat: Kein Ubuntu-Derivat

Version: gar kein Ubuntu

Architektur: 64-Bit PC

Desktop: unbekannt

  • Nachricht senden

2

25.01.2013, 19:08

Du könntest uns auch mal die Fehlermeldung posten.

Zitat

Weiss jemand wo man dieses Zeug, welches Poettering raucht, kaufen kann? Und brennt das dann auch mit nem normalen Feuerzeug? Oder brauch ich da jointd dazu, um den Rauch zu erzeugen?

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

3

25.01.2013, 20:32

Hab etwas dran weitergearbeitet, hier also der etwas überarbeitete Code:

Quellcode

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <iostream> 
#include <ostream>

using namespace std;

FILE *out;
int i,j,N,jahr,tagn,anf,end,days;
int s1;
char heute;
char zeit;
char anf_s, end_s;
int zufall1,zufall2;
double anf1, anf2, end1, end2, temp1, temp2;



int main(void)
{
	out=fopen("stundenabrechnung.csv", "w");

	
	printf("Dieses Programm erstellt Ihnen für ein Jahr eine Stundenabrechnung.\n\
	Bitte Jahreszahl eingeben:");
	scanf("i%", &jahr);
	
	fprintf(out,"Stundenabrechnung für das Jahr %i\nDatum;Tag;Von;Bis;Dauer[h];\
	Gesamt[h]\n", jahr);
	
	printf("Was war der erste Tag im Jahr?");
	scanf("d% (Montag=1, Dienstag=2, Mittwoch=3, Donnerstag=4, Freitag=5\
	Samstag=6, Sonntag=7", &s1);
	printf("Wie viele Tage hat dieses Jahr?");
	scanf("%d", &days);
	
	printf("Wann fangen sie frühestens an zu arbeiten? Eingabe bitte\
	nur ganz- oder halbzahlig (z.B. 9.00 Uhr = 9 oder 9.30 Uhr = 9.5)\n");
	scanf("%d", &anf1);
	printf("Wann fangen sie spätestens an zu arbeiten? Eingabe bitte\
	nur ganz- oder halbzahlig (z.B. 9.00 Uhr = 9 oder 9.30 Uhr = 9.5)\n");
	scanf("%d", &end1);
	///Erstelle mir ein kleines Zeitintervall von n*30 Minuten. n=temp1 verwende
	///ich später als obere Grenze bei meiner Zufallszahl.
	temp1=1+(end1-anf1)*2;
           	
	printf("Wann hören sie frühestens auf zu arbeiten? Eingabe bitte nur\
	ganz- oder halbzahlig (z.B. 17.00 Uhr = 17 oder 17.30 Uhr = 17.5)\n");
	scanf("%d", &anf2);
	printf("Wann hören sie spätestens auf zu arbeiten? Eingabe bitte\
	nur ganz- oder halbzahlig (z.B. 17.00 Uhr = 17 oder 17.30 Uhr = 17.5)\n");
	scanf("%d", &end2);
	temp2=1+(end2-anf2)*2;
	
	for(i=1;i<=days;i++)
	{
    	///Die for-Schleife soll so durchlaufen, dass sie alle 365 / 366 Tage
    	///des Jahres durchläuft. Ist der Tag kein FR, SA, SO soll tagn++. 
    	///Ansonsten kommen noch andere Befehle hinzu.
    	if(tagn==5)
    	{
     	///Erstellt mir die zwei Zufallszeit wann ich anfange / aufhöre zu
     	///arbeiten. Allerdings wird diese Funktion garnet erst richtig
     	///ausgeführt, da wohl etwas mit dem Zufallsgenerator nicht stimmt.
     	zeiten();
     	///Soll mir einen String anhand meines doubles anf ausgeben.
     	anf_s=zeitzaehler(anf); 
     	end_s=zeitzaehler(end);
     	heute = ("FR");
     	fprintf(out," ;%s;%s;%s;%d; \n",heute,anf_s,end_s,end-anf);
     	///Kann man eine Berechnung wie hier, "end-anf" einfügen???
     	tagn++;
    	}
    	if(tagn==6)
    	{
     	time();
     	anf_s=zeitzaehler(anf); 
     	end_s=zeitzaehler(end);     	
     	heute = "SA";
     	fprintf(out," ;%s;%s;%s;%d; \n",heute,anf,end,end-anf);
     	tagn++;
    	}
    	if(tagn==7)
    	{
     	time();
     	anf_s=zeitzaehler(anf); 
     	end_s=zeitzaehler(end);     	
     	heute = ("SO");
     	fprintf(out," ;%s;%s;%s;%d; \n",heute,anf,end,end-anf);
     	tagn=0;
    	}
     	else
     	tagn++;
	}
}

void zeiten()
{         	
	///Gibt mir eine Zufallszahl zwischen 0 und temp1 bzw. temp2 aus.
	srand(time(NULL));
	zufall1 = rand() % temp1 + 0;
	srand(time(NULL));
	zufall2 = rand() % temp2 + 0;
    	
	///Berechne mir eine "künstliche" Zeit an der ich zu arbeiten beginne.
	anf = anf1+zufall1*0.5;
	end = anf2+zufall2*0.5;
	///Werden mir die beiden doubles anf und end auch so zur weiteren Berechnung
	///zur Verfügung stehen??
	return anf, end;
}

char zeitzaehler(double res)
{
   	///Ist meine Zeit "voll", dann soll als Uhrzeit dargestellt werden. Z.B.
   	/// temp1 = 9 => string "9:00"
   	if(res%1 == 0)
   	return zeit=("%d:00",res);

   	///Ist meine Zeit "halbvoll", dann soll als Uhrzeit dargestellt werden.
   	///Z.B. temp1 = 9.5 => string "9:30"   	
   	else
   	{
       	res=res-0.5;
       	return zeit=("%d:30",res);
   	}
}


In folgenden Zeilen gibt es Probleme:

#66: "zeiten" nicht deklariert
#68: "zeitzaehler" nicht deklariert
#70: ungültige umzuweisung von "const char" nach "char"
#85 zu wenig argumente für die Funktion "time_t time(time_t*)"

Es gibt noch ein paar mehr, allerdings wiederholen sie sich. Ich verstehe vor allem nicht in wie fern ich die zwei Unterfunktionen (sagt man das so?) nicht richtig deklariert habe. Hab das so eigentlich aus einer anderen Aufgabe übernommen.
Falls ihr noch etwas zu meinen Kommentaren sagen könntet, wäre das echt super :)

Gruß der grillmeister

  • »maettu« ist männlich

Beiträge: 3 299

Registrierungsdatum: 14.09.2005

Derivat: Xubuntu

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

4

25.01.2013, 22:36

Zitat

#66: "zeiten" nicht deklariert

#68: "zeitzaehler" nicht deklariert
Du musst die Funktionen deklarieren, oder einfach die Funktionsblöcke vor main setzen (quick and dirty-Lösung, geht glaube ich aber nicht bei allen Compilereinstellungen)
Hier steht so einiges zu C/C++, im ersten Codeschnipsel wird gezeigt wie die Funktion f deklariert wird.

Zitat

#70: ungültige umzuweisung von "const char" nach "char"
falscher Dateityp, für "heute" würde ich ein char-array nehmen, so:

Quellcode

1
char[2] heute;

wobei die 2 hier für die Anzahl Buchstaben steht.

Zitat

#85 zu wenig argumente für die Funktion "time_t time(time_t*)"
ziemlich selbsterklärend, du musst time wohl mit einem Argument aufrufen, das wird wohl eine Zahl sein.

PS: Vielleicht fängst du zunächst mal etwas kleiner an. Ein Programm welches eine Zahl einliesst, dann ausbauen mit den Zufallszahlen usw...

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

5

26.01.2013, 13:31

Ok, hab den Code mal zusammengekürzt:

Quellcode

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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

///Zufallsgenerator: Läuft!
int zufall(int t){
  int random;
  srand (time (NULL));
  random = (rand () % (t + 1)); 
  return (random);
}

char zeitzaehler(double res)
{
 	char zeit[5];
 	double mod;
 	double tpp;
 	
 	tpp = res;
 	
   	///Ist meine Zeit "voll", dann soll als Uhrzeit dargestellt werden. Z.B.
   	/// res = 9 => string "9:00"
   	mod = (res % 1.);
   	if(mod == 0){
   	return zeit=("%d%s", res, ':00');
   	}

   	///Ist meine Zeit "halbvoll", dann soll als Uhrzeit dargestellt werden.
   	///Z.B. tpp = 9.5 => string "9:30"   	
   	else{
       	tpp=tpp-0.5;
       	return zeit=("%d%s", res, ':30');
   	}
}

int main(void)
{
	int s, e;
	double z1;
	char end[5];
	
	printf("Gib mir eine Startzeit:\n");
	scanf("%d", &s);
	printf("Gib mir eine Endzeit:\n");
	scanf("%d", &e);
	/// s < e !!!
	z1 = zufall(1+(s-e)*2);
	end = zeitzaehler(s+z1*0.5);
	
	printf("Start: %d, Ende: %d, Zufall &d, Daten: &c\n",s,e,z1,end);
	
	system("PAUSE");
	return 0;
}


Der Zufallsgenerator läuft soweit schon mal. Probleme machen mir die Deklarationen für meine Zeichenketten und komischer Weise auch das Modulo...

Hier der Fehlercode:
In function `char zeitzaehler(double)':
23: error: invalid operands of types `double' and `double' to binary `operator%'
25:34: warning: multi-character character constant
25: error: incompatible types in assignment of `int' to `char[5]'
32:38: warning: multi-character character constant
32: error: incompatible types in assignment of `int' to `char[5]'
In function `int main()':
48: error: incompatible types in assignment of `char' to `char[5]'

Geht das überhaupt das ich "zeitzaehler" mit einem double füttere und eine Zeichenkette rausbekomme? Kann es sein das Modulo sich nicht mit Double verträgt?

Gruß der grillmeister

  • »maettu« ist männlich

Beiträge: 3 299

Registrierungsdatum: 14.09.2005

Derivat: Xubuntu

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

6

26.01.2013, 14:14

Zitat

Kann es sein das Modulo sich nicht mit Double verträgt?
Modulo ist eine "Ganzzahl-Operation", das macht mit Kommazahlen kein Sinn. Folglich musst du bei Modulo immer ein Ganzzahl-Typ nehmen, was meistens int entspricht.
Weisst du überhaupt was Modulo macht, mathematisch gesehen? Falls nicht bitte in Wikipedia oder so nachlesen.

Die Zeit würde ich übrigens mit integers machen, sprich eine für Stunden, Minuten, usw...

Du machst eine Mischung zwischen Berechnungen mit Zeit, und der Darstellung der Zeit. Das trennst du am besten, indem du wie schon geschrieben Ganzzahlen für die Berechnungen nimmst.
Um nachher eine schöne Darstellung der Zeit zu haben, programmierst du eine Funktion die als Argumente Stunden, Minuten, ... hat und den Namen "PrintTime", dort schaust du dass beispielsweise nur von 0 bis 59 Minuten ausgegeben wird, natürlich musst du bei grösseren Minutenzahlen die Stunden entsprechend anpassen.

PS: Wenn du willst würde sich ein struct für die Zeit anbieten, das wäre dann eine Art Zusammenfassung von verschiedenen Variabeln. Structs finden sich übrigens in jedem gueten C/C++ Tutorial.

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

7

26.01.2013, 15:13

Jup, mir ist schon bewusst was Rechnen mit Modulo bedeutet, es ist einfach das Rechnen mit Rest. Ich bin nur davon ausgegangen, dass C sich nicht komplett an die mathematische Definition wendet, sondern das auch so Sachen wie 5 : 2,2 = 2, Rest 0,6 möglich wären. Google hat aber auch hier einen Rat parat, die Funktion nennt sich

Quellcode

1
fmod(double x, double y)

Siehe hier!

Von einem Struct habe ich noch nie was gehört, da muss ich mich erst einlesen! Aber danke für den Tipp mit der Zeit, denke mit einer while-Schleife könnte sich da was machen lassen.

Gruß der grillmeister

P.S: Wie handl ich das eigentlich wenn mir eine Funktion f(int x) 2 Werte zurückgibt (int y,int z), dass ich mit y und z in main weiterarbeiten kann?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »grillmeister« (26.01.2013, 16:03)


  • »maettu« ist männlich

Beiträge: 3 299

Registrierungsdatum: 14.09.2005

Derivat: Xubuntu

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

8

26.01.2013, 16:16

fmod das f steht hier für "float" damit ist eine Fliesspunktzahl gemeint, nur brauchst du das definitiv nicht, da du so oder so mit Ganzzahlen arbeitest.

Zitat

mod = (res % 1.);
hier wandelst du die "1" in eine Fliesskommazahl (float) um, da du "1." schreibst, solche impliziten Umwandlungen sollten dir bewusst sein.
Res Modulo 1 macht eh wenig Sinn (das ist doch die Ganzzahldivision durch 1, was bei Ganzzahlen immer = 0 ist) okay ausser du denkst an das fmod und willst die Nachkommazahl haben, die bekommst du so:

Quellcode

1
2
float res, nachkommazahl;
nachkommazahl = res - (int)res;

einiges simpler, weniger Rechenintensiv.

Zitat

Aber danke für den Tipp mit der Zeit, denke mit einer while-Schleife könnte sich da was machen lassen.
Immer eine while-Schleife brauchen, naja nicht sehr intelligent bei 3 Parametern...

PS: dein "Zeitzähler" soll bemerken ob es Punkt (:00) oder Halb (:30) ist, bei einer Zeiteingabe, oder soll das eher eine Rundenfunktion sein, da bei dir nur auf Halbestunden abgerechnet wird?

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

9

26.01.2013, 17:21

C/C++-Quelltext

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
int zeitzaehler(int res, int *a, int *b)
{
	int j=0;
	while(res>=60){
  	j++;
  	res-=60;
	}
	*a = j;
	*b = res;
}

int main(void)
{
	int s, e, temp, temp2, z1, a, b;
	
	printf("Gib mir eine Startzeit:\n");
	scanf("%d", &s);
	printf("Gib mir eine Endzeit:\n");
	scanf("%d", &e);
	temp=((e-s)*2+1);
	z1 = zufall(temp);
	temp2=(s*60+z1*30);
	
	printf("Start: %i, Ende: %i, Zufall %i, Start: %i:%i\n",s,
	e,z1,zeitzaehler(temp2, &a, &b));
	
	system("PAUSE");
	return 0;
}


#20: temp gibt mir jetzt ein Intervall von n halbstündigen Werten. Sind Anfangs und Endzeit identisch, ist temp = 1.
#21: aus dem Intervall lasse ich mir eine Zufallszahl z1 ausgeben.
#22: wandelt die Startzeit in Minuten um und addiert z1*30 Minuten hinzu.

Die Gesamtzeit in Minuten durchläuft jetzt die while-Schleife, wobei am Ende j die Stunden darstellen sollen und res die restlichen Minuten. j und res will ich jetzt wieder an main übergeben, aber iwas stimmt noch nicht.

Zitat

PS: dein "Zeitzähler"
soll bemerken ob es Punkt (:00) oder Halb (:30) ist, bei einer
Zeiteingabe, oder soll das eher eine Rundenfunktion sein, da bei dir nur
auf Halbestunden abgerechnet wird?


Eigentlich war es mal so gedacht, dass die Stundenanzahl nur "voll" oder "halbvoll" sein kann und genau das soll erkannt werden. Aber ich denke das habe ich mit dem neuen Zeitzähler umgangen.

Zitat

hier wandelst du die "1" in eine Fliesskommazahl (float) um, da du "1."
schreibst, solche impliziten Umwandlungen sollten dir bewusst sein.
Ich dachte eigentlich das "1." immer exakt 1 bedeutet, auch wenn ich die Zahl als float darstelle. Damit kein 1,0000000009 o.ä. bei rauskommt.

Zitat

Res Modulo 1 macht eh wenig Sinn
Das stimmt schon, aber zu dem Zeitpunkt dacht ich ja noch das Modulo auch Kommazahlen annimmt.

Ob mein C-Code sonderlich intelligent ist oder nicht, dass sei dahin gestellt. Mir gehts erstmal nur darum die einzelnen Befehle zu verstehen und anwenden zu können, sodass mein Programm so läuft wie ich es will.


--
Fredl findet, daß das mit passenden Code-Tags viel netter aussieht.

  • »maettu« ist männlich

Beiträge: 3 299

Registrierungsdatum: 14.09.2005

Derivat: Xubuntu

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

10

26.01.2013, 18:13

Zitat

Ich dachte eigentlich das "1." immer exakt 1 bedeutet, auch wenn ich die
Zahl als float darstelle. Damit kein 1,0000000009 o.ä. bei rauskommt.
Du musst dir im klaren sein, was die einzelnen Dateitypen bedeuten. Wie z. B. int, float,... du schaust dir am besten mal hier die Tabelle an, dort wird gezeigt welchen Wertebereich die einzelnen Datentypen haben.

Zitat

j und res will ich jetzt wieder an main übergeben, aber iwas stimmt noch nicht.

Quellcode

1
zeitzaehler(temp2, &a, &b);

arbeitet mit den Pointern a und b, das Resultat steht nach dem Aufruf in der Variable a und b. D. h. du musst vor printf die Zeitzaehler-Funktion aufrufen und dann ist das Resultat in den Variable a und b gespeichert.
Und folglich dann beim printf a und b ausgeben.
Deine zeitzähler-Funktion sollte als Rückgabewert im Prinzip void haben, es gibt wohl so oder so eine Warning da du kein Rückgabewert in dieser Funktion hast.


Du solltest dich mit den Begriffen "Call by Value" und "Call by Reference" und Pointer noch etwas beschäftigen.

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

11

27.01.2013, 15:27

Also zum Großteil funktioniert es jetzt schon! :) Trotzdem muss ich dich maettu noch mit ein paar Fragen quälen ;D

Programmausschnitt:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	printf("Dieses Programm erstellt Ihnen f\x81r ein Jahr eine Stundenabrechnung.\
Bitte Jahreszahl eingeben:\n");
	scanf("i%", &jahr);
	fflush(stdin);

	if ( schaltjahr(jahr) )
    	tij=366;
	else
    	tij=365;

	start_tag = starttag(jahr);

	out=fopen("stundenabrechnung.csv", "w");
	fprintf(out,"Stundenabrechnung für das Jahr %i\n", jahr);


Nach der Eingabe der Jahreszahl als Int in Zeile 3, soll mir das Programm in meine "Exceltabelle" stundenabrechnung den Text "Stundenabrechnung für das Jahr XY" reinschreiben. Den Text übernimmt es, die Zahl jedoch nicht. Hab ich z.B. "2012" eingegeben, kam 55 raus oder auch 8-10 stellige Zahlen (geschätzt). Warum funktioniert das nicht? Schreibe ich eine beliebige Zahl anstelle von %i funktioniert es. Hab mir das Beispiel auch auf verschiedenen anderen Seiten angeschaut und die machen es genauso ?( Versuche mit %d oder %f schlugen genauso fehl.

Später werden noch weitere Daten in die .csv Datei geschrieben. Muss ich die Datei dann nochmal mit fopen öffnen?

Manchmal kommt es vor das mein Ausgabetext länger ist als der Bildschirm breit (siehe Zeile 1 und 2). Durch \ + Enter kann ich zwar in der nächsten Zeile weiterschreiben, aber ich hätte gern den Text unterhalb des Textanfangs, also das es so aussieht:

Quellcode

1
2
fprint("Dieses Programm.....
    	Bitte Jahres....


Versuche ich das im Editor, so habe ich später auch die Leerzeichen/Tabs im Text, was nicht Sinn der Sache ist. Vorschlag wie ich dem Kompiler klar mache das ich die Leers nicht haben will?

Gruß der grillmeister

  • »maettu« ist männlich

Beiträge: 3 299

Registrierungsdatum: 14.09.2005

Derivat: Xubuntu

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

12

27.01.2013, 17:47

Zitat

scanf("i%", &jahr);
ich würde dir empfehlen das % vor dem i zu schreiben, du kannst im Prinzip immer den gleichen Formatierungsstring nehmen wie beim printf.
Du kannst auch %d nehmen, wie ja bei den bisherigen Code-Schnipsel funktioniert hat. Die Frage ist auch noch welcher Datentyp "jahr" ist, der muss natürlich übereinstimmen, sollte integer sein falls eine Ganzzahl gewünscht ist.
Sonst schau dir mal hier das an: http://openbook.galileocomputing.de/c_vo…ausgabe_001.htm

Zitat

Später werden noch weitere Daten in die .csv Datei geschrieben. Muss ich die Datei dann nochmal mit fopen öffnen?
soweit ich weiss solltest du einmal öffnen und dann am Schluss noch die Datei schliessen. Das ganze mit den Files ist nicht ganz einfach, also wenn man es richtig mit einer gewissen Fehlersicherheit machen will.

Quellcode

1
out=fopen("stundenabrechnung.csv", "w");

dabei kann es Fehler geben und somit out=NULL sein, was sich bei den folgenden Befehlen sehr schlecht macht. Schau mal hier , da steht in etwa was ich meine.

Zitat

Manchmal kommt es vor das mein Ausgabetext länger ist als der Bildschirm
breit (siehe Zeile 1 und 2). Durch \ + Enter kann ich zwar in der
nächsten Zeile weiterschreiben, aber ich hätte gern den Text unterhalb
des Textanfangs, also das es so aussieht:
Kommt wohl auf den Editor an, du kannst aber glaube ich mit "Tabulator" nach vorne rücken, das sollte glaube ich bei printf überlesen werden, bin aber nicht ganz sicher.

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

13

27.01.2013, 20:48

Endlich is mein kleines Programm fertig!!! Vielen Dank maettu das du so geduldig warst und mich immer unterstützt hast! :) :) :)

Hier nun das fertige Programm:

Quellcode

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>

char tg[4];

int zufall(int z)
{
	time_t t;
	time(&t);
	srand((unsigned int)t);
	return (rand() % z );
}

void zeitzaehler(int *a, int *b, int res){
	int j=0;
	while(res>=60){
    	j++;
    	res-=60;
	}
	*a = j;
	*b = res;
	///return 0;
}

int schaltjahr(int j){
	if ( j % 4 == 0 && j % 100 != 0 || j % 400 == 0 )
    	return 1;
	else
    	return 0;
}

int starttag(int j){
	int i,temp=0;

	for(i=2001;i<j;i++){
   	if(schaltjahr(i))
   	temp+=366;
   	else
   	temp+=365;
	}
	temp %= 7;
	return temp; ///temp=1 für 2012
}

int monatszaehler(int tagn, int jahr, int *tag, int *monat ){
	int f;
	if(jahr==366)
    	f = 1;
	else
    	f = 0;

	if(tagn<=31) ///Januar
    	return (*tag=tagn, *monat=1);
	else if( 59+f >= tagn) ///Februar
    	return (*tag=tagn-31, *monat=2);
	else if( 90+f >= tagn) ///März
    	return (*tag=tagn-59-f, *monat=3);
	else if((120+f)>=tagn) ///April
    	return (*tag=tagn-90-f, *monat=4);
	else if((151+f)>=tagn) ///Mai
    	return (*tag=tagn-120-f, *monat=5);
	else if((181+f)>=tagn) ///Juni
    	return (*tag=tagn-151-f, *monat=6);
	else if((212+f)>=tagn) ///Juli
    	return (*tag=tagn-181-f, *monat=7);
	else if((243+f)>=tagn) ///August
    	return (*tag=tagn-212-f, *monat=8);
	else if((273+f)>=tagn) ///September
    	return (*tag=tagn-243-f, *monat=9);
	else if((304+f)>=tagn) ///Oktober
    	return (*tag=tagn-273-f, *monat=10);
	else if((334+f)>=tagn) ///November
    	return (*tag=tagn-304-f, *monat=11);
	else return (*tag=tagn-334-f, *monat=12); ///Dezember

}

void tageszaehler(int tag){
	switch(tag){
    	case 0 : strcpy(tg, "Mo") ; break;
    	case 1 : strcpy(tg, "Di") ; break;
    	case 2 : strcpy(tg, "Mi") ; break;
    	case 3 : strcpy(tg, "Do") ; break;
    	case 4 : strcpy(tg, "Fr") ; break;
    	case 5 : strcpy(tg, "Sa") ; break;
    	case 6 : strcpy(tg, "So") ; break;
    	}
}

int main(void){
	FILE *out;
	int tag_jahr, tij, start_tag, k;
	int m; ///Laufvariable
	char tag[20];
	float anf1[7], anf2[7], end1[7], end2[7];
	double temp1[7], temp2[7];
	int tester[7];
	int jahr, p=1;

	int i, l;
	double zufall_start[7], zufall_ende[7];
	int a,b,c,d,e,f,g,h;
	int tep1[7], tep2[7];

	printf("Dieses Programm erstellt Ihnen f\x81r ein Jahr eine Stundenabrechnung.\nBitte Jahreszahl eingeben:\n");
	scanf("%i", &jahr);
	fflush(stdin);

	if ( schaltjahr(jahr) )
    	tij=366;
	else
    	tij=365;

	out=fopen("stundenabrechnung.csv", "w+");
	fprintf(out,"Stundenabrechnung für das Jahr %d\n\n Datum ; Tag ; Von ; Bis ; Dauer[h] ; Gesamt[h]\n", jahr );

	for(m=0;m<7;m++)
	{
	switch(m)
    	{
    	case 0 : strcpy(tag, "Montag") ; break;
    	case 1 : strcpy(tag, "Dienstag") ; break;
    	case 2 : strcpy(tag, "Mittwoch") ; break;
    	case 3 : strcpy(tag, "Donnerstag") ; break;
    	case 4 : strcpy(tag, "Freitag") ; break;
    	case 5 : strcpy(tag, "Samstag") ; break;
    	case 6 : strcpy(tag, "Sonntag") ; break;
    	}

	printf("Arbeitest du am %s ? (Ja=1, Nein=0)\n\n", tag);
	scanf("%i", &k);
	fflush(stdin);
	printf("\n");

	if(k==1)
    	{
    	tester[m]=1;

    	printf("Wann f\x84ngst du am %s fr\x81hestens an zu arbeiten? Eingabe nur ganz- oder halbzahlig (z.B. 9:00 Uhr = 9 oder 9:30 Uhr = 9.5)\n", tag);
    	scanf("%f", &anf1[m]);
    	fflush(stdin);
    	printf("Wann f\x84ngst du am %s sp\x84testens an zu arbeiten? Eingabe nur ganz- oder halbzahlig (z.B. 9:00 Uhr = 9 oder 9:30 Uhr = 9.5)\n", tag);
    	scanf("%f", &end1[m]);
    	fflush(stdin);

    	printf("Wann h\x94rst du am %s fr\x81hestens auf zu arbeiten? Eingabe nur ganz- oder halbzahlig (z.B. 17:00 Uhr = 17 oder 17:30 Uhr = 17.5)\n", tag);
    	scanf("%f", &anf2[m]);
    	fflush(stdin);
    	printf("Wann h\x94rst du am %s sp\x84testens auf zu arbeiten? Eingabe nur ganz- oder halbzahlig (z.B. 17:00 Uhr = 17 oder 17:30 Uhr = 17.5)\n", tag);
    	scanf("%f", &end2[m]);
    	fflush(stdin);

    	temp1[m] = (int)(1+(end1[m]-anf1[m])*2);
    	temp2[m] = (int)(1+(end2[m]-anf2[m])*2);
    	}
	else
    	{
    	printf("Du faule Socke ;)\n\n");
    	tester[m]=0;
    	temp1[m]=0;
    	temp2[m]=0;
    	}
	}

	start_tag = starttag(jahr);
	for(i=1;i<=tij;i++)
	{
    	if(tester[start_tag] == 1)
    	{
        	zufall_start[start_tag] = (rand() % (int)(1+(end1[start_tag]-anf1[start_tag])*2));
        	zufall_ende[start_tag] = (rand() % (int)(1+(end2[start_tag]-anf2[start_tag])*2));

        	tep1[start_tag] = ((int)((anf1[start_tag]*60)+(zufall_start[start_tag]*30)));
        	tep2[start_tag] = ((int)((anf2[start_tag]*60)+(zufall_ende[start_tag]*30)));

        	zeitzaehler(&a, &b, tep1[start_tag] );
        	zeitzaehler(&c, &d, tep2[start_tag] );

        	zeitzaehler(&e, &f, ( (c-a)*60+(d-b) ));
        	tageszaehler(start_tag);

        	monatszaehler(i,tij,&g,&h);

        	///         	Datum 	Tag  	Von     	Bis  	Dauer[h]    	Gesamt[h]
        	fprintf(out," %02d.%02d. ; %s ; %02d:%02d ; %02d:%02d ; %02d:%02d \n",g,h,tg,a,b,c,d,e,f);
    	}

    	start_tag++;
    	if(start_tag % 7 == 0)
    	{
        	fprintf(out,"\n");
        	p++;
    	}

    	start_tag %= 7;
	}

printf("\nDie Stundenabrechnung wurde erfolgreich erstellt und steht dir nun unter dem Namen "Stundenabrechnung.csv" im gleichen Ordner wie \
dieses Programm zur Verf\x81gung.\n\nBeachte gegebenfalls noch die \x9A \berschneidung mit eventuellen Feiertagen.\n\n");
system("PAUSE");

}


Noch irgendwelche Verbesserungsvorschläge? Ansonsten kann der Thread von mir aus geschlossen werden.

Gruß der grillmeister

DocHifi

unregistriert

14

27.01.2013, 20:52

Ansonsten kann der Thread von mir aus geschlossen werden.

Das musst du schon selber machen. :D
1.Beitrag bearbeiten und Präfix setzen.

15

27.01.2013, 21:17

Noch irgendwelche Verbesserungsvorschläge?
Wie ich in #9 schon eingefügt habe: C- statt Code- Tags...
Ansonsten kann der Thread von mir aus geschlossen werden.
Von mir aus auch. Und der und der und der und der und der und der auch, wenn du schon dabei bist.
Beim Erstellen dieser Nachricht kamen keine Tiere zu Schaden.
me is all sausage
but don't call me Ferdl

16

28.01.2013, 00:47

Danke für's "gelöst" setzen der anderen Themen!
Beim Erstellen dieser Nachricht kamen keine Tiere zu Schaden.
me is all sausage
but don't call me Ferdl

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

17

29.01.2013, 11:18

Kein Problem! :) Aber da es uns Usern, wie du gesagt hast, offen steht ein Thema zu reaktivieren, möchte ich dies hier gerne tun.

Es geht um ein N-Teilchen Problem. Im "Lösungscode" steht das ganze zusammengefasst so da:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
double *x ///Zeiger x deklariert, x sammelt die gesamten Koordinaten aller Teilchen auf, sollte somit ein 1-dim Array sein
int N;
...
scanf("%d", N); ///Teilchenanzahl N festgelegt
...
x=(double*)malloc(N*sizeof(double)); ///Speicher reservieren für den Vektor x der Größe "N*double"
...
for(i=0;i<N;i++)
{
x[i] = 0.0; ///Startpunkt aller N-Koordinaten auf 0 setzen
}
...


Ich frage mich ob man das ganze auch in etwa so hätte schreiben können:

Quellcode

1
2
3
int N;
scanf("%d", N);
double x[N] ={0.0};


Wenn ich das richtig verstanden habe laut Wiki: C-Programmierung, dann muss ich das im ersten Fall nur so kompliziert machen, weil ich nicht weiß wie groß N überhaupt ist, oder? Oder wird mir im 2. Fall nur Speicher für eine N*"0" und nicht für N*"double" reserviert?

Gruß der grillmeister

  • »maettu« ist männlich

Beiträge: 3 299

Registrierungsdatum: 14.09.2005

Derivat: Xubuntu

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

18

29.01.2013, 12:02

Zitat

dann muss ich das im ersten Fall nur so kompliziert machen, weil ich nicht weiß wie groß N überhaupt ist, oder?
dein zweiter Code funktioniert nicht, da N zur Laufzeit nicht bekannt ist. Deshalb ist es für den Compiler unmöglich den Speicherplatz für "double x[N]" zu reservieren.
Du kannst für N einen fixen Wert eingeben, wenn du weisst, dass der Vektor x nicht grösser als was weiss ich werden kann.
Z. B. "double x[100]" damit reservierst du mal den Speicherplatz für 100 double-Zahlen, was dann je nach System 100 mal 4Byte oder so ist (nicht immer optimal).

Wenn du aber Probleme hast mit variabel langen Vektoren, ist die Methode mit malloc die einzig richtige. Du solltest auch pro malloc je ein free haben, also so machen das Programmierer die am Ende ihres Programmes aufräumen.
Bei anderen Sprachen als C übernimmt das "aufräumen" meist ein "Garbage Collector" (vgl. Java)

Zitat

Oder wird mir im 2. Fall nur Speicher für eine N*"0" und nicht für N*"double" reserviert?
Speicherplatz wird für das Objekt also den "double" reserviert, es ist egal welche Zahl darin gespeichert wird. Jeder double braucht immer gleich viel Platz im Speicher, es muss theoretisch möglich sein den kleinsten oder grössten Wert eines doubles darin zu speichern.

  • »grillmeister« ist männlich
  • »grillmeister« ist der Autor dieses Themas

Beiträge: 32

Registrierungsdatum: 15.05.2012

Derivat: Kubuntu

Architektur: 32-Bit PC

Desktop: KDE4

  • Nachricht senden

19

29.01.2013, 15:50

Danke für deine schnelle Antwort maettu! :)

Meinen Code hab ich grad mal ausprobiert -> geht tatsächlich nicht :D

Sehe ich das dann richtig das *x auf mein Array im Speicher verweist? Weil mir ist noch nicht so ganz klar, warum ich x Anfangs als Pointer definiere, ihn aber später wie ein 1-dim Array verwenden kann (x[i] etc.)[/i]

  • »maettu« ist männlich

Beiträge: 3 299

Registrierungsdatum: 14.09.2005

Derivat: Xubuntu

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

20

29.01.2013, 17:21

Zitat

warum ich x Anfangs als Pointer definiere, ihn aber später wie ein 1-dim Array verwenden kann (x[i] etc.)[/i
Pointer und Arrays sind verwandt. Das Stichwort hier heisst "Pointeraritmetik", dein Array macht das indirekt auch. Oder auch auf Deutsch nach "Zeiger und Vektoren" suchen.


x heisst im Prinzip folgendes mit Worten ausgedrückt:
-gehe an die Adresse von x
-gehe i mal sizeof( double) wäre normalerweise etwa 4 Bytes im Speicher weiter
-lese was dort im Speicher steht oder schreibe an diesen Speicherort.

das ganze lässt sich auch mit Pointern formulieren, nur viel komplizierter.

Aber ich denke mal du solltest dir ein C-Buch zulegen, dort werden solche Sachen genauer erklärt und auch meistens mit Programmierbeispielen gezeigt.
Bei Pointern lohnt es sich übrigens den Speicher zu zeichnen, in etwa so wie in diesem lustigen Video zu Pointern.