Zahlen aus Textdatei lesen und in Integer Variable speichern
-
Danke für die Tipps! Werde jetzt erst einmal versuchen, damit etwas auf die Beine zu stellen
Zwei Fragen hätte ich trotzdem noch so am Rande!
Du hast geschrieben "Position merken". Kleiner Tipp von dir wie das funktioniert?
Und die zweite: Gibt es irgendeine recht simple Möglichkeit die Werte in der txt
nach der Zeit zu sortieren? Falls nicht, erhalte ich ja beim einlesen alles Werte durcheinander gewirbelt!Danke schon mal!
-
Der Rückgabewert von strchr ist ein char* also ein Zeiger auf char.
Ach, schau mal da: http://www.cplusplus.com/reference/cstring/strchr/
Sieh dir da auch mal strrchr an.
Da kannst du auch sehen, wie du an die Position hinter dem ':' kommst.
-
hab mir jetzt mal das zusammengebastelt
FILE *FDatei; FDatei = fopen("C:\\Highscore.txt", "r"); char score[20]; char *sc; fgets(score, 20, FDatei); sc = strchr(score, ':'); high[0] = strtol(score,&sc,10); printf("\n\n %l", high[0])
;
jedoch passiert nun nicht allzuviel. Es wurden lediglich die letzen zwei Zeichen, d.h. von "22.00s" nur "0s" ausgegeben. Eine Idee was da so alles falsch sein könnte?
-
Da werden nicht die Nullen gelesen, sondern nichts.
high[0] = strtol(sc+1,NULL,10);
bei sc steht der ':' als ist bei sc+1 das Zeichen dahinter.
Du solltest aber vorher prüfen ob überhaupt ein ':' gefunden wurde.
Wenn du allerdings Kommazahlen hast, ist strtol nicht geeignet.
Da musst du dann strtod nehmen. Undhigh
muss dann vom Typ double sein.score darf auch größer sein.
-
okay das habe ich jetzt alles soweit. Ich verstehe nur irgendwie nicht was bei fgets die 20 in der Klammer bedeutet.
Wenn ich diese auf 16 einstelle, gibt er mir 22.00 aus, stelle ich z.B. auf 26, dann geht gar nichts mehr. Was hat das zu bedeuten?
-
RTFM!
-
Weißt du denn was die 20 in den [] bei score bedeutet?
Könnte das was miteinander zu tun haben, weil du auch bei fgets score angibst?Nebenbei: "Manuel's Zeit: 42s" sind schon 18 Zeichen. Da kommt noch die Terminierung dazu. Meinst du da reichen 20 Zeichen aus?
(Ja, Ok. Da reicht es gerade. Aber es gibt auch längere Namen als Manuel)Ach ja, das FM zum lesen: http://www.cplusplus.com/reference/cstdio/fgets/
-
Ja ich weiß was das bedeutet
habs jetzt auch raus mit dem fgets. Ich bin mitlerweile bei diesem Code
angelangt und kann im Moment keinen klaren Gedanken mehr fassen bin am Endevoid highscore() { system("cls"); FILE *FDatei; FDatei = fopen("C:\\Highscore.txt", "r"); char score[40]; char *sc; for(int i=0; i<=19;i++) { fgets(score, 40, FDatei); sc = strchr(score, ':'); high[0] = strtod(score,&sc+1); printf("\n %d", high[0]); } fclose(FDatei);
Allerdings kommt er laut dem Debugger nie bei der Zeile "high[0] = strtod(score,&sc+1);" an.
Ich hoffe jemand kann mich jetzt endgültig aufklären wie ich das gebacken kriege
-
char score[] = "Lisa's Zeit: 24s\n"; // simuliertes Einlesen per fgets char* sc = strchr ( score, ':' ); /* Die Funktion strchr liefert dir einen Zeiger auf das erste Vorkommen eines ':' innerhalb des char-Arrays score, oder NULL wenn kein ':' vorkommt. Wir prüfen also: */ if ( NULL != sc ) { // Wenn die if-Anweisung in diesen Block verzweigt, wurde ein ':' gefunden. printf ( "Ein ':' wurde gefunden!" ); // Dient lediglich zur Veranschaulichung zur Laufzeit, was im Programm abgeht. // Der char-Zeiger sc zeigt jetzt also auf den ':' innerhalb des char-Arrays. // Das kann man sich(hoffentlich) so veranschaulichen: // Lisa's Zeit: 24s\n" // ^ // | // sc // // Soweit, so gut. Der Zeiger zeigt auf den Doppelpunkt, ein Doppelpunkt lässt sich hier // jedoch hier nicht sinnvoll in eine Zahl umwandeln. // Jetzt musst du also dafür sorgen das die Funktion strtod einen // Zeiger übergeben bekommt, der auf den Anfang der einzulesenden Zahl zeigt. // Da strtod führende Whitespaces (Leerzeichen, Tabulatoren, Zeilenumbrüche) ignoriert ( kann man nachlesen http://www.cplusplus.com/reference/cstdlib/strtod/ ), // genügt es, dass dein Zeiger auf das Leerzeichen vor der Zahl zeigt: // Lisa's Zeit: 24s\n" // ^ // | // sc // Das erreichst du durch die Inkrementation von sc um 1. // Was du jedoch machst, du übergibst an strtod den Anfang des Arrays selbst: // Lisa's Zeit: 24s\n" // ^ // | // sc // // Was verständlicherweise nicht funktionieren kann. Wozu der zweite Parameter von // strtod gut ist, kannst du ebenfalls nachlesen ... }
-
Du benutzt die PAramter bei strtod falsch.
high[0] = strtod(sc+1, NULL);
-
Danke für die lange Erklärung CJosef und natürlich auch an DirkB.
Ich habe mir eure Ratschläge und die eines alten Freundes zu Herzen genommen und nun diesen Code erhalten.
Jedenfalls funktioniert es immer noch nicht
Bei der Überprüfung, ob er ein ":" findet, sagt er dass er dies tut.
Im Endeffekt spuckt er aber trotzdem nur jede Menge Nullen aus.system("cls"); FILE *FDatei; FDatei = fopen("C:\\Highscore.txt", "r"); char score[100]; char* sc; fgets(score, 40, FDatei); // Ist es wirklich sinnig es vor der Klammer zu überprüfen? sc = strchr ( score, ':' ); if ( NULL != sc ) { for(int i=0; i<=19;i++) { fgets(score, 40, FDatei); sc = strchr ( score, ':' ); high[i] = strtod(sc+1,NULL); // Was ist denn jetzt noch falsch?? Hab alles gemacht wie ihr meintet... printf("\n %d", high[i]); } } else { printf("Lesen des Highscores fehlgeschlagen"); } fclose(FDatei);
-
// Was ist denn jetzt noch falsch?? Hab alles gemacht wie ihr meintet...
strtod gibt double zurück.
Der format specifier für printf http://www.cplusplus.com/reference/cstdio/printf/ und der Datentyp deines Arrays müssen also dazu passen.double high [ LINES_MAX ]; printf ( "%f\n", high [ 0 ] );
// Ist es wirklich sinnig es vor der Klammer zu überprüfen?
Das war schon ein klein wenig anders gemeint.
Generell sollte der Rückgabewert von strchr nach jedem Aufruf stattfinden, strtod könnte dein Programm zum Absturz bringen, wenn NULL als erster Parameter übergeben wird.
Das wäre der Fall, wenn deine Datei eine Leerzeile enthält oder wenn das Dateiformat nicht stimmt, wenn also kein ':' in einer Zeile gefunden wird.#include <stdio.h> #include <stdlib.h> // strtod #include <string.h> // strchr #define LINES_MAX 50 #define LINELEN_MAX 512 //enum nLines { lines_max = 100 }; int main ( void ) { char* fname = "test.txt", *eptr, *p; char score [ LINELEN_MAX ]; char score_separator = ':', seconds_symbol = 's'; unsigned i = 0; double high [ LINES_MAX ]; FILE *fp = fopen ( fname, "r" ); if ( NULL == fp ) { perror ( fname ); return 0; } while ( i < LINES_MAX && NULL != fgets ( score, sizeof ( score ), fp )) { if ( NULL != ( p = strchr ( score, score_separator ))) { high [ i ] = strtod ( p + 1, &eptr ); if ( seconds_symbol == *eptr ) printf ( "%f\n", high [ i++ ] ); } else { printf ( "score separator '%c' not found in line %u\n", score_separator, i + 1 ); } } printf ( "%u records read\n", i ); if ( i >= LINES_MAX && ! feof ( fp )) puts ( "Caution: maybe not all scores could be read!" ); if ( NULL != fp ) fclose ( fp ); return 0; }
-
Wahrscheinlich ist CJosefs Beispiel wesentlich professioneller, vielleicht langt für eine Schulaufgabe aber auch folgendes:
#include <stdlib.h> #include <stdio.h> #include <string.h> int main ( void ) { int high[100]; char score[100]; char* sc; int i = 0; FILE *FDatei; system("cls"); FDatei = fopen("C:\\Highscore.txt", "r"); if (!FDatei) { perror ("fopen: "); return 1; } while (fgets(score,40,FDatei) != NULL) { sc = strchr ( score, ':' ); if (sc) { printf ("score: %s",score); high[i] = strtod(sc+1,NULL); printf ("high[%d]: %i\n",i,high[i]); ++i; } } if (ferror(FDatei)) // fgets hat NULL gemeldet, aber Datei ist noch nicht zu Ende { perror ("fgets:"); return 2; } fclose(FDatei); return 0; }
viele grüße
ralph
-
Falls es einfach?? gehen soll, empfehle ich einen Blick auf