Einlesen von Text
-
Also, ich habe schon ein paar mal versucht folgendes zu lösen, bin aber nicht so recht talentiert, was das Programmieren betrifft.
Ich möchte eine Textdatei einlesen:Beispiel
N001 G01 X34,45Y122,53Z2343,12und das über viele Zeilen eben so weiter.
Jetzt kommts aber:
Denn ich möchte die Zahlen ja zum weiterrechnen und so benutzen.
Das heißt ich muss irgendwie Zeile für Zeile abtasten und sobald das X gefunden wird, die Zahlen danach irgendwohin speichern/schreiben als Variable zum Beispiel (float Datentyp wahrscheinlich wegen 2 Kommastellen). dann soll es weiter abtasten bis Y gefunden wird und das selbe wieder und dann noch Z und das selbe!
Nur die Kommastellen bleiben zwar immer gleich, also von den Werten her nicht, aber es sind immer zwei Stellen, also auch 10 ist dann halt 10,00! also das ist nicht das Problem. Nur das sich eben die Positionen der Zahlen ändern, dadurch, dass ja die Zahlen auch länger oder kürzer sein können.
So ist dann halt auch X1,12 möglich und auch X1413121,32So muss ich irgendwie erkennen wann X ist und Y und ...!
Und die Zahlen dann von dem eingelesenen char umwandeln um float zu erhalten, halt damit ichs weiterverarbeiten kann!Prinzipiell einlesen ist nicht das Problem, das kann ich mit textdateien denke ich. aber so, dass es was erkennt und ichs dann weiterverwenden kann, inklusive den Kommastellen, da ja C immer nur ein Komma als Punkt('.') erkennt, aber in der Textdatei die geliefert wird das Komma eben normal ist (',')
Kann mir wer so einfach wies geht helfen?
Also einfach nur den Code will ich einlesen können in C und dann irgendwie die Zahlen da drinnen benutzen können und eben X,Y,Z zuordnen können.Mein Ziel ist es eben, dass ich dann schreibe zb. A=sqrt[(X2)(Y2)]
und ich mir dann A ausgeben lassen kann als printf.Hilfe, bin nicht faul, nur ich kenn mich mit Datenbanken und sowas aus, aber mit C relativ wenig, oder eben nur grundlegendes.
DANKE IM VORAUS
Alexander
-
Also nur mal so als Stichpunkte:
zeilenweise aus Datei einlesen mit
char *fgets(char *buffer, int anzahlZeichen, FILE *datei)
String zerlegen in Einzelteile mit
char *strtok(char *string, const char *trennZeichen)
in den zerlegten Strings Zeichen (in deinem Fall das Komma) suchen mit
char *strchr(const char *string, int suchZeichen)
Den Punkt kannst du dann mittels des zurückgelieferten Pointers draufschreiben.
String nach float-Zahl wandeln mit
double atof(const char *string)
-
Alexander2183 schrieb:
Also, ich habe schon ein paar mal versucht folgendes zu lösen, bin aber nicht so recht talentiert, was das Programmieren betrifft.
Aber gleich nen Matheparser programmieren wollen, oder wie. Dafür mus man zwar nicht sonderlich talentiert sein, aber eine Textdatei einlesen muss schon drin sein.
Alexander2183 schrieb:
Ich möchte eine Textdatei einlesen:
Das ist doch schonmal ein Anfang.
Naja und dann sowas hier: 34,4523 in einen double Wert zu bekommen, dafür gibt es fertige Funktionen, strtod z.B., Nachdem du in einem Puffer das Komma durch nen Punkt ersetzt hast.
Oder aber, wenn du es selber machen willst, wird es recht umfangreich.
Wäre aber eine gute Übung, wenn du auf einen Matheparser hinaus willst. Der ist ist dann noch um einiges Umfangreicher.
Bedenke, was alles für Zeichen in einer double-Zahl vorkommen können: E,e,+,- usw.; eine double Zahl kann ja auch so aussehen: double d = -.1E-2; (-0,001)
Dafür würde ich dann eine zweidimensionale Funktionszeigertabelle erstellen, die je nachdem welches Zeichen gerade aktuell ist, eine Funktion aufruft.Ein möglicher Ansatz ist erst einmal das:
#include <stdio.h> FILE* fp=NULL; double x=0,y=0,z=0; double get_num () { // ... to be written. } double get_x () { x = get_num (); } double get_y () { y = get_num (); } double get_z () { z = get_num (); } int main( int arg, char* argv[] ) { int c=0; fp = fopen ("test.txt", "rb"); if ( !fp ) return 0; while ( c != EOF ) { c = fgetc (fp); switch (c) { case 'X': get_x (); break; case 'Y': get_y (); break; case 'Z': get_z (); break; } } fclose(fp); return 0; }
Gruß,
p.C.
-
Was bedeutet das to be written, was gehört da zum beispiel rein???
Is irgendwie alles schwer zu verstehen für mich.
aber eins kann ich sagen:
E-0,3 ... sowas kann bei mir nicht vorkommen, ausschließlich sowas:N001 G01 XzahlYzahlZzahl
und N001 und G01 haben keine bedeutung!also nichts extrem kompliziertes nötig!
trotzdem danke!
-
Habs jetzt mal so probiert:
#include <stdio.h> #include <string.h> #include <conio.h> #include <math.h> FILE* fp=NULL; double x=0,y=0,z=0; double get_num () { } double get_x () { x = get_num (); } double get_y () { y = get_num (); } double get_z () { z = get_num (); } int main( int arg, char* argv[] ) { int c=0; fp = fopen("C:\\Ich.txt","r"); if ( !fp ) return 0; while ( c != EOF ) { c = fgetc (fp); switch (c) { case 'X': get_x (); printf("%d",get_x); getchar(); break; case 'Y': get_y (); printf("%d",get_y); getchar(); break; case 'Z': get_z (); printf("%d",get_z); getchar(); break; } } fclose(fp); return 0; }
und es kommt mit ne Zahl raus immer, also drei eigentlich, da ich ja X,Y,Z habe, aber die Zahlen entsprechen nicht denen, die in der Textdatei stehen, wieso das?
aber sonst, schon voll coooool!
wenn das noch passen würde dann, wär mir leichter!
-
Alexander2183 schrieb:
aber die Zahlen entsprechen nicht denen, die in der Textdatei stehen, wieso das?
Unter anderem, weil der Aufruf get_x**()** get_y**()** usw. sein müsste.
get_x, get_y, sind keine Funktionsaufrufe, das würdest du so schreiben wenn du einen Zeiger auf eine Funktion mit einem Wert fütterst.Ich habe den Ansatz ein bisschen aus-/umgebaut für long-Werte. Wie mann dann auf double-Werte kommt, überlasse ich dir, ne.
Es findet keine Bereichsüberprüfung statt! ( LONG_MAX, LONG_MIN )#include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <limits.h> #define NUMLENMAX 10 FILE* fp = NULL; long x=0,y=0,z=0; char buf [NUMLENMAX+1]={0}; long get_num () { int c = 0; int i = 0; memset(buf,0,sizeof(buf)); while (isdigit(c=fgetc(fp))) { buf[i++] = c; if ( i == NUMLENMAX ) { printf( "Buffer full!" ); break; } } ungetc(c,fp); return atol(buf); } long get_x () { x = get_num (); printf ( "x = %ld\n", x ); } long get_y () { y = get_num (); printf ( "y = %ld\n", y ); } long get_z () { z = get_num (); printf ( "z = %ld\n", z ); } int main( int arg, char* argv[] ) { int c=0; fp = fopen ("test.txt", "rb"); if ( !fp ) return 0; while ( c != EOF ) { c = fgetc (fp); switch (c) { case 'X': get_x (); break; case 'Y': get_y (); break; case 'Z': get_z (); break; } } fclose(fp); return 0; }
-
bei mir steht "memset undeclared"
was heißt das?
-
habe memset einmal weggelöscht und jetzt gehts!
DANKE!
das einzige ist, dass wenn die Zahl ne kommazahl ist, das es das ganze irgendwie ned nimmt, was nach dem komma steht!
weißt du warum?dann quäl ich dich nimma
-
Komma ist ein deutsches Dezimaltrennzeichen. Du mußt schon nen Punkt nehmen. Also entweder du ersetzt das Komma oder parst die Werte manuell.
-
Habe eh einen Punkt verwendet und es liest trotzdem nur die Zeichen ein, die vor dem Punkt sind!
wieso das?
-
Alexander2183 schrieb:
habe memset einmal weggelöscht und jetzt gehts!
DANKE!das ist aber megamäßig unempfehlenswert!
probieama das da drüba: #include <string.h>
-
Das er nur die Werte vor dem Punkt oder Komma liest liegt daran, dass du sie in Integer Variablen und nicht in Float Variablen packst.
-
Nimm das hier, dann kannste die Kommas auch drin lassen.
double num = 0; int quotient = 0; while(isdigit(c = fgetc(fp))) { num = num * 10 + (c - '0'); } // catch floating points if(c == ',') { quotient = 1; while(isdigit(c = fgetc(fp))) { num = num * 10 + (c - '0'); quotient *= 10; } num /= quotient; } ungetc(c, fp);
Hab ich jetzt nicht geteste aber sollte funzen, evtl mußt du schauen, daß er sobal isdigit false wird, den nächsten Buchstaben, den er ja schon gelesen hat, wieder zurücktust. Aber ich würde hier eigentlich eher mit einem Linebuffer arbeiten, wenn ich du wäre.
-
Nur mal so interessehalber:
Was spricht dagegen die Funktionen, die ich vorgeschlagen habe zu verwenden? Ist an denen irgendwas verkehrt? Irgendwie finde ich das eine viel unkompliziertere Lösung.#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { char str[] = "N001 G01 X34,45Y122,53Z2343,12"; // das Einlesen aus der Datei schenke ich mir jetzt mal char *start, *strX, *strY, *strZ, *comma; double x, y, z; start = strtok(str, "X"); strX = strtok(NULL, "Y"); strY = strtok(NULL, "Z"); strZ = strtok(NULL, " "); comma = strchr(strX, ','); *comma = '.'; comma = strchr(strY, ','); *comma = '.'; comma = strchr(strZ, ','); *comma = '.'; x = atof(strX); y = atof(strY); z = atof(strZ); return 0; }
-
Stichpunktgeber schrieb:
Nur mal so interessehalber:
Was spricht dagegen die Funktionen, die ich vorgeschlagen habe zu verwenden? Ist an denen irgendwas verkehrt? Irgendwie finde ich das eine viel unkompliziertere Lösung.#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { char str[] = "N001 G01 X34,45Y122,53Z2343,12"; // das Einlesen aus der Datei schenke ich mir jetzt mal char *start, *strX, *strY, *strZ, *comma; double x, y, z; start = strtok(str, "X"); strX = strtok(NULL, "Y"); strY = strtok(NULL, "Z"); strZ = strtok(NULL, " "); comma = strchr(strX, ','); *comma = '.'; comma = strchr(strY, ','); *comma = '.'; comma = strchr(strZ, ','); *comma = '.'; x = atof(strX); y = atof(strY); z = atof(strZ); return 0; }
Ne Frage:
Kannst du mir dass vielleicht nochmal senden mit der Stelle inklusive wo ich die datei einlese, irgendwie gehts bei mir ned, wenn ichs selbst mache!
Damit es geht wenn ich mit dem selben code compiliere!
danke
-
Ach ja, und ne frage:
wenn ich, was ja möglich ist, einmal nur ne X Koordinate habe und kein Z oder Y, oder einmal nur X und Z und so weiter habe, geht das dann trotzdem?am einfachsten fand ich den ersten Code:
#include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <limits.h> #include <string.h> #define NUMLENMAX 10 FILE* fp = NULL; float x=0,y=0,z=0; char buf [NUMLENMAX+1]={0}; float get_num () { int c = 0; int i = 0; memset(buf,0,sizeof(buf)); while (isdigit(c=fgetc(fp))) { buf[i++] = c; if ( i == NUMLENMAX ) { printf( "Buffer full!" ); break; } } ungetc(c,fp); return atol(buf); } float get_x () { x = get_num (); printf ( "x = %f\n", x ); getchar(); } float get_y () { y = get_num (); printf ( "y = %f\n", y ); getchar(); } float get_z () { z = get_num (); printf ( "z = %f\n", z ); getchar(); } int main( int arg, char* argv[] ) { int c=0; fp = fopen ("C:\\Ich.txt", "rb"); if ( !fp ) return 0; while ( c != EOF ) { c = fgetc (fp); switch (c) { case 'X': get_x (); break; case 'Y': get_y (); break; case 'Z': get_z (); break; } } fclose(fp); return 0; }
Hier war nur das Problem, das es mir nicht die Zahlen nach dem Komma bzw. '.' ausgibt aus der textdatei, sondern nur die davor!
ich wünsch mir zum glück nur nen code, der genau wie hier gegeben, auch geht bei mir, mit dem doofen komma und auch wenn ich mal nur ne bestimme koordinate habe, nicht alle drei!
-
bloss keinen finger selber krumm machen oder wie.
-
Habs ja eh versucht, ich weiß nur ned wie ichs zum laufen kriege.