Ich grüße euch.
Ich habe gerade ein Programm in C geschrieben bei dem der Anwender zwei
Uhrzeiten im Format hh:mm eingeben kann. Diese Zeiten werden als
einzelne Arrays eingespeichert. Dann übergebe ich die Arrays an eine
Funktion.
Hier rechne ich das Array erst einmal um, um die richtigen Zahlen zu
erhalten. (Zwecks Ascii-Tabelle).
Danach rechne ich mit den Zeiten ein bisschen und gebe die Differenz in
3 Formaten raus:
Stunden:Minuten,
Minuten,
Stunde dezimal
Wenn ich das Programm so laufen lasse kommen allerdings ganz komische
Zahlen heraus und die Differenzen sind in jedem Format 0.
Stimmt jetzt das einlesen nicht? Die Übergabe an die Funktion mittels
Pointer oder ist die Umrechnung in eine „richtige“ Zahl falsch?
Ich finde irgendwie den Fehler nicht.
Vielen Dank im Vor raus, hier noch mein C-Code:
Tobias Straub schrieb:> Ich habe gerade ein Programm in C geschrieben
Hallo Tobias,
als erstes mal die Frage, willst du Berechnungen in C üben, oder soll
das Programm einfach seinen Zweck erfüllen?
Wenn zweiteres der Fall ist, könntest du die zwei Zeiten mit den
time-Funktionen, die in C enthalten sind, jeweils umrechnen in die
Unix-Zeit (z.B. mktime). Dann die beiden subtrahieren und die Differenz
einfach zurückwandeln z.B. in einen String (z.B. ctime oder asctime).
einzige Voraussetzung: #include <time.h>
npn schrieb:> Tobias Straub schrieb:>> Ich habe gerade ein Programm in C geschrieben>> Hallo Tobias,>> als erstes mal die Frage, willst du Berechnungen in C üben, oder soll> das Programm einfach seinen Zweck erfüllen?> Wenn zweiteres der Fall ist, könntest du die zwei Zeiten mit den> time-Funktionen, die in C enthalten sind, jeweils umrechnen in die> Unix-Zeit (z.B. mktime). Dann die beiden subtrahieren und die Differenz> einfach zurückwandeln z.B. in einen String (z.B. ctime oder asctime).>> einzige Voraussetzung: #include <time.h>
Es ist eine Aufgabe von der Hochschule. Ich möchte das Programmieren
üben. Vor allem auch die Übergabe von Funktionen. Anwendungen mit Arrays
und und und. Also sollte es eher so gemacht werden wie ich es
geschrieben habe. Allerdings finde ich hierbei keinen Fehler.
Das mit dem Debuggen ist nicht meine Stärke haha. Aber ich werde es mal
versuchen. Habt ihr denn schon einen Fehler in meinem Programm gefunden?
Tobias Straub schrieb:> Habt ihr denn schon einen Fehler in meinem Programm gefunden?
Nein, habe ich nicht.
Ich habe es auch gar nicht genau angeschaut.
Grund: das ist ein typischer Fehler, den man mit einem Debugger leicht
findet, und das ist eine Grundfertigkeit zum Programmieren.
Also darfst du dich da gerne selber reinfuchsen.
Ohne jede Gehässigkeit - wenn man sowas noch nicht gemacht hat, wird es
Zeit.
Klaus Wachtler schrieb:> Nein, habe ich nicht.> Ich habe es auch gar nicht genau angeschaut.>> Grund: das ist ein typischer Fehler, den man mit einem Debugger leicht> findet, und das ist eine Grundfertigkeit zum Programmieren.> Also darfst du dich da gerne selber reinfuchsen.>> Ohne jede Gehässigkeit - wenn man sowas noch nicht gemacht hat, wird es> Zeit.
Hey,
also habe gerade mal mit dem Debugger durchgeschaut. Hierbei habe ich
erkannt das er in meinem String am Anfang die zahlen 51 und 52 jeweils
drin stehen hat und beim beschreiben der Strings es nicht annimmt.
Was könnte der fehler an meinem scanf_s sein?
Das habe ich noch verändert:
N. A. schrieb:> Kleiner Tip: Nutze das Unix Time Format.
Habe ich auch schon vorgeschlagen, geht aber nicht:
Tobias Straub schrieb:> Es ist eine Aufgabe von der Hochschule. Ich möchte das Programmieren> üben. Vor allem auch die Übergabe von Funktionen. Anwendungen mit Arrays> und und und. Also sollte es eher so gemacht werden wie ich es> geschrieben habe.
Tobias Straub schrieb:> Stimmt jetzt das einlesen nicht?
Wer oder was hindert dich daran, das Eingelesene gleich nach der Eingabe
erst mal zur Sicherheit wieder auszugeben? Nur so, einfach nur um zu
sehen, ob das auch alles geklappt hat.
Stimmt. Nichts hindert dich
> int main()> {> char uhrzeit1[6], uhrzeit2[6];> printf("Bitte geben Sie zwei Uhrzeiten ein (hh:mm)\n");> printf("1. Uhrzeit:\n");> scanf_s("%s", uhrzeit1, 5);> fflush(stdin);> printf("2. Uhrzeit:\n");> scanf_s("%s", uhrzeit2, 5);
1
printf("Erste Eingabe: '%s'\n",uhrzeit1);
2
printf("Zweite Eingabe: '%s'\n",uhrzeit2);
> Funktion_Berechnung(uhrzeit1, uhrzeit2);> }
und schon brauchst du nicht mehr uns fragen, sondern dein Programm
'erzählt' dir, was du wissen willst.
Merke: Es ist nicht verboten, sich während der Entwicklungsphase sein
Programm mit printf zu spicken, so dass einem das Programm selbst
erzählt, was es an welcher Stelle warum tut.
Die printf kommen dann wieder raus, wenn alles fertig ist und alles
sieht so aus, als ob es immer und von Anfang an so gewesen wäre.
Das ist das Debugging des kleinen Mannes. Ein echter Debugger hat seine
Vorteile, etwas flexibler reagieren zu können. Dafür hat die printf
Methode den Vorteil, dass man erstens keine externen Werkzeuge benötigt
und man zweitens die printf von einer Debug Sitzung zur nächsten
'mitnehmen' kann. Ist eine Ausgabe erst mal im Programm, so erfolgt die
Ausgabe bei jedem Testlauf und man kann untersuchen ob und was sich
verändert hat. Speziell wenn die Datenstrukturen dann schon mal
komplexer werden, können Debugger da selten mithalten.
Praktisch gesehen muss man mit beidem umgehen können.
Noch was: wenn Funktionen einen Wert zurückliefern, macht es Sinn diesen
Rückgabewert auch mal anzuschauen. Zusammen mit der Doku der Funktion
hat man gelegentlich dann auch eine Idee, was schiefläuft.
Und noch ein kleiner Tip.
Lies in deinen Unterlagen nach, was ein %s in der Format-Liste bei einem
scanf ganz genau macht. Und dann stell das mal in Beziehung zu den
Tasten, die du drückst. Und merke: Auch ein Return ist ein Tastendruck,
der zu deinem Programm "durchgestellt" wird und der daher beim scanf
ankommt.
Klaus Wachtler schrieb:> Noch was: wenn Funktionen einen Wert zurückliefern, macht es Sinn diesen> Rückgabewert auch mal anzuschauen. Zusammen mit der Doku der Funktion> hat man gelegentlich dann auch eine Idee, was schiefläuft.
Meine Funktion liefert doch gar nichts zurück. Ich gebe nur die Arrays
an die Funktion und in der Funktion mache ich dann auch die Ausgabe...
Das mit dem printf zur überprüfung hab ich gerade gemacht (mach ich
öfters so). Das Problem ist jetzt das er mir für die erte zeit genau den
string gibt den ich einlese, also bei mir 07:00 aber die zweite zeit
zeigt er mir mittels der printf gar nicht an....
das ist voll komisch
Hab jetzt mit dem printf nochmal überprüft was mein scanf überhaupt
einliest. Als ausgabe kommt bei beiden "(null)"
Das bedeutet doch das er meine zahlen überhaupt nicht speichert oder?
Und null weil ich das array oben eben mit nullen fülle...
Aber ich hab nachgeschaut, ein string liest man so ein.
Kann mir bitte einer eine lösung geben?
Grüße
Tobias Straub schrieb:> Hab jetzt mit dem printf nochmal überprüft was mein scanf überhaupt> einliest. Als ausgabe kommt bei beiden "(null)"> Das bedeutet doch das er meine zahlen
Zahlen?
Wieso Zahlen?
Du hast keine Zahlen. Du hast erst mal nur Texte. An dieser Stelle ist
es noch völlig unerheblich ob du "07:00" oder "Test" eingibst. Text ist
Text und nur weil da einige Zeichen Ziffernzeichen sind, hast du noch
lange keine Zahlen.
> überhaupt nicht speichert oder?> Aber ich hab nachgeschaut, ein string liest man so ein.> Kann mir bitte einer eine lösung geben?
Hast du direkt über deinem Posting von 18:21 mein Posting gesehen?
Das ist nämlich wichtig, dass du diesen Zusammenhang verstehst und was
da abgeht.
Naja ich deklariere ein String mit 6 Zeichen, da ich 5 Zeichen eingebe
(hh:mm) und das 6. Zeichen halte ich für das 0 Glied frei zum beenden
des Strings. Und beim scanf_s also beim einlesen, lese ich dann aber nur
5 Zeichen ein:
scanf_s("%s", &uhrzeit1[5]);
fflush(stdin);
printf("2. Uhrzeit:\n");
scanf_s("%s", &uhrzeit2[5]);
fflush(stdin);
Und danach lösche ich noch den Tastaturpuffer um jeglichen Mist
rauszuscheisen denn ich nicht will.
Mach ich denn dabei etwas falsch?
Habe gerade einfach mal in die zwei arrays schon eine feste uhrzeit
eingeben. also
char uhrzeit1[6] = { 0,7,':',3,0 }, uhrzeit2[6] = { 0,8,':',3,0};
Dann rechnet er auch alles aus, egal was ich in mein bölödes scanfs
einlese. Das heißt der scanf_s funktioniert eindeutig nicht. Aber ich
finde einfach nicht den Fehler was ich ändern muss.
Please help :)
Tobias Straub schrieb:> Und danach lösche ich noch den Tastaturpuffer um jeglichen Mist> rauszuscheisen denn ich nicht will.
Tja
Nur. Genau genommen ist überhaupt nicht definiert, was ein
fflush(stdin)
überhaupt macht.
Es ist zwar eine weit verbreitete Annahme, das dieses alle noch
wartenden Zeichen aus dem Eingabestrom rausschiesst. Aber wie das mit
Annahmen eben so ist ....
Karl Heinz schrieb:> Tobias Straub schrieb:>>> scanf_s("%s", &uhrzeit1[5]);>> &uhrzeit[5] ?
Du sagst deinem scanf damit:
Hier, das ist mein Array, in dem das Ergebnis landen soll
1
+---+---+---+---+---+---+
2
| | | | | | |
3
+---+---+---+---+---+---+
und mittels &uhrzeit[5] sagst du dem scanf: Das eingelesene bitte ab
hier
1
+---+---+---+---+---+---+
2
| | | | | | |
3
+---+---+---+---+---+---+
4
^
5
|
6
hier
ablegen.
Tja.
Ich würde ja mal sagen, der scanf sollte beim Einlesen vorne im Array
anfangen und nicht mitten drinn.
Klaus Wachtler schrieb:> Aber im ursprünglichen Qelltext stand das noch anders...
:-)
Wie meistens.
Planloses rumprobieren ohne zu wissen, was eigentlich das Problem ist.
OK.
Machen wirs kurz
dein Problem ist
* das sich der scanf, so wie du den Format Specifier geschrieben hast,
den Return NICHT aus dem Eingabestrom holt. Wodurch der 2.te scanf als
erstes Zeichen den Return sieht und damit seinerseits die Eingabe
bereits für beendet erklärt, noch ehe es zu den interessanten Zeichen
kommt.
* das das Verhalten fflush(stdin) nicht definiert ist. Insbesonders ist
es wohl auf deinem System so, dass dieses einfach nichts macht.
Insbesondere nicht den Eingabebuffer ausleert.
Wenn du Strings einlesen willst, dann ist scanf keine so gute Wahl. Um
Strings einzulesen nimmt man besser fgets, welches eine Menge Probleme
löst. Insbesondere die, die dich jetzt plagen. Aber Achtung: fgets liest
auch den \n vom Eingabestrom und speichert ihn im String ab! Du musst
also Platz dafür vorsehen.
Problem GELÖST:
Beim scanf_s muss ich ihm ja sagen wie viel Zeichen er einlesen darf.
Habe das ja auch gemacht mit ",5". ABER ich muss ja ",6" machen weil er
ja das beenden zeichen auch nich braucht. So nen Sch*** haha
Sorry für das nerven aber auch vielen Dank für eure Hilfe. Ihr seit
super!
Grüße
Karl Heinz schrieb:> OK.> Machen wirs kurz>> dein Problem ist> * das sich der scanf, so wie du den Format Specifier geschrieben hast,> den Return NICHT aus dem Eingabestrom holt. Wodurch der 2.te scanf als> erstes Zeichen den Return sieht und damit seinerseits die Eingabe> bereits für beendet erklärt, noch ehe es zu den interessanten Zeichen> kommt.> * das das Verhalten fflush(stdin) nicht definiert ist. Insbesonders ist> es wohl auf deinem System so, dass dieses einfach nichts macht.> Insbesondere nicht den Eingabebuffer ausleert.>> Wenn du Strings einlesen willst, dann ist scanf keine so gute Wahl. Um> Strings einzulesen nimmt man besser fgets, welches eine Menge Probleme> löst. Insbesondere die, die dich jetzt plagen. Aber Achtung: fgets liest> auch den \n vom Eingabestrom und speichert ihn im String ab! Du musst> also Platz dafür vorsehen.
Jap, genau das war das Problem. =)
Du kannst auch einen Whitespace (z.B,. Leerzeichen) in den Formatsring
vom scanf einbauen.
Das weist scanf an, Whitespaces zu überlesen (so sie denn vorhanden
sind)
Karl Heinz schrieb:> das das Verhalten fflush(stdin) nicht definiert ist. Insbesonders ist> es wohl auf deinem System so, dass dieses einfach nichts macht.> Insbesondere nicht den Eingabebuffer ausleert.
Das stdafx.h und auch das scanf_s deuten doch sehr stark auf Visual
Studio/Windows hin.
Und von da kommt ja das unsägliche fflush(stdin)
Ich habe jetzt nicht den gesamten Thread gelesen, aber ich würde
folgende Strategie verwenden. Die ist für den User simpel,
nachvollziehbar und man muss sich nicht mit selbstgestrickten
Kalenderfunktionen herumärgern:
- Startzeit (Datum und Uhrzeit) in "total seconds" umrechnen
- Endzeit ebenso
- Startzeit von Endzeit abziehen
- Ergebnis von total seconds nach d:h:m:s formatieren ...
Als Basis für "total seconds" benutzen versch. Prog.-Sprachen versch.
Bezugstermine, z.B. den 01.01.1900 00:00 oder andere, oft gibts diese
Funktion auch "fertig" oder als Lib zum Hinzufügen.
Für die Eingabe würde ich irgend eine starre (!) Maske mit Auf- und
Ab-Pfeil bzw. +- in einer Textumgebung machen. Das bewahrt vor mühsamem
Parsing ... denn jeder Depp schreibt was Anderes, wenn er kann ... das
entfällt dann enfach :-)