Datei parsen
-
Hallo,
ich hab es jetzt versucht zu realisieren, habe aber einige Probleme dabei,
ich habe folgende Datei:Ich bins=567 Du bist es=54Hallasd test=Hallo
Mit dem unteren Programm lese ich zuerst die Datei in ein char- Array ein und dann rufe ich die Funktion translate auf, welche mir z.B.: in unterem Fall für test -> Hallo zurückgeben soll.
Ich weiß jetzt nicht, wie ich das am besten realisiere,Die Funktion sollte im Endeffekt das machen, dass ich zwei char[] Arrays der Funktion übergebe, ein char[] - Array soll obige Info enthalten und das zweite char[]- Array entwält einen Text:
z.B.: Ich habe Ich bins Haustiere und test.
und aus diesem Satz sollte nach translate:
Ich habe 567 Haustiere und Hallo.
also einfach parsen und übersetzen.
Vielleicht könnte mir da jemand helfen.
Vielen Dank,
lg#include <stdlib.h> #include <stdio.h> #include <string.h> char* getTranslation(char string[], char test[]); int main(int argc, char** argv) { FILE *file; int letter; if( ( file = fopen( "test", "r")) == NULL) { puts("Cannot oepn the file"); } char dest[300]; int x = 0; while( ( letter = fgetc(file) ) != EOF) { dest[x++]=letter; } fclose(file); char test[] = {'t', 'e', 's', 't', '\0'}; getTranslation(dest, test); return (EXIT_SUCCESS); } char* getTranslation(char mapping[], char test[]) { char translated[200]; char * pch; pch = strtok (mapping,"="); while (pch != NULL) { printf("-------------------------%s\n", pch); pch = strtok (NULL, "="); } return translated; }
-
Generic1 schrieb:
Ich weiß jetzt nicht, wie ich das am besten realisiere
Ich schlage vor, du verwendest strncmp. Du bekommst aber bestimmt noch ein anderes Problem. Wenn du Deine Textdatei ausliest, sieht
dest
in etwa so aus:Ich bins=567\nDu bist es=54Hallasd\ntest=Hallo
Wenn du das nur am '=' trennst, wirst du dies bekommen:
Ich bins 567\nDu bist es 54Hallasd\ntest Hallo
Jetzt kannst du selbst ein wenig überlegen
-
Hallo,
eine Frage hätte ich noch,
wenn ich den String "hallo=ich" mit dem unteren Code zerlege, dann muss ich mit der Zeile value = strtok (NULL, "="); den value Zeiger auf "ich" setzen um ich auszugeben.Ich habs mit value[1] versucht, den Zeiger auf ich zu setzen aber das funkt nicht.
Weiß vielleicht jemand, wie ich mir diese Zeile spare und den value Zeiger gleich auf "ich" setzen kann?Und eine zweite Frage hätte ich auch noch, gibts eine Funktion, die das selbe macht wie strtok und wenn es kein token gibt (z.B.: in diesem Fall -> Hallo=),
dann nichts macht, Momentan wird bei mir ein Fehler geworfen (unten ist die fertige Funktion)Vielen Dank,
lgif(strncmp(pch, test, strlen(test)) == 0) { char * value = strtok (pch,"="); value = strtok (NULL, "="); printf("%s\n", value); //printf("Passt test %s und pch %s \n", test, pch); }
Momentane Funktion:
void getTranslation(char mapping[], char test[], char translated[]) { char * pch = strtok (mapping,"\n"); while(pch != NULL) { if(strncmp(pch, test, strlen(test)) == 0) { char * value = strtok (pch,"="); value = strtok (NULL, "="); strcpy(translated, value); } pch = strtok (NULL, "\n"); } }
-
Generic1 schrieb:
Hallo,
eine Frage hätte ich noch,
wenn ich den String "hallo=ich" mit dem unteren Code zerlege, dann muss ich mit der Zeile value = strtok (NULL, "="); den value Zeiger auf "ich" setzen um ich auszugeben.Ich habs mit value[1] versucht, den Zeiger auf ich zu setzen aber das funkt nicht.
Weiß vielleicht jemand, wie ich mir diese Zeile spare und den value Zeiger gleich auf "ich" setzen kann?value
ist kein Array, deshalb wirst du mitvalue[1]
nicht sehr weit kommen. Ich würde hier wirklich mitsscanf
arbeiten.Generic1 schrieb:
Und eine zweite Frage hätte ich auch noch, gibts eine Funktion, die das selbe macht wie strtok und wenn es kein token gibt (z.B.: in diesem Fall -> Hallo=),
dann nichts macht, Momentan wird bei mir ein Fehler geworfen (unten ist die fertige Funktion)Du bekommst wahrscheinlich den Fehler, weil
value == NULL
. Du müsstest also erst überprüfen, ob'sNULL
ist und erst dannstrcpy
anwenden.Deine (korrekte) Variante:
void getTranslation(char mapping[], char test[], char translated[]) { char * pch = strtok (mapping,"\n"); while(pch != NULL) { if(strncmp(pch, test, strlen(test)) == 0) { char * value = strtok (pch,"="); value = strtok (NULL, "="); if (value) strcpy(translated, value); } pch = strtok (NULL, "\n"); } }
Die
sscanf
-Variante:void getTranslation (char mapping[], char test[], char translated[]) { char * pch = strtok (mapping, "\n"); while (pch != NULL) { if (strncmp (pch, test, strlen (test)) == 0) sscanf (pch, "%*[^=]%*c%[^\n]", translated); pch = strtok (NULL, "\n"); } }
-
Vielen Dank für die Hilfe, klappt super,
Eine Frage hätte ich noch, ich hab jetzt einen Text:char text[] = {"Hallo test ich bins"}; char result[900];
Den möchte ich jetzt mit der obigen Methode übersetzen, d.h. als erstes "Hallo" wird z.B: durch das Mapping (Hallo=Servus) nach Servus, test wird übersetzt nach "wie gehts" usw.
Das Ergebnis soll in das char- Array "result" geschrieben werden.Was mir nicht ganz klar ist, wie kann ich z.B.: nur Hallo aus dem Array text rausnehmen -> übersetzen ist dann klar, und dann beim Array result anhängen?
Vielen Dank für die Hilfe!!
lg
Generic
-
Generic1 schrieb:
Was mir nicht ganz klar ist, wie kann ich z.B.: nur Hallo aus dem Array text rausnehmen -> übersetzen ist dann klar, und dann beim Array result anhängen?
Du musst bis zum Whitespace lesen und diesen Teil rausnehmen. Kannst du doch mit
strtok
machen, also am Leerzeichen trennen. Zum Anhängen kannst du strncpy oder strncat.
-
Hallo,
Danke für die Antwort, ich hab jetzt versucht, das zu machen (unten), leider wird getTranslation nur einmal aufgerufen, ich vermute weil ich 2 mal strtok (NULL, " "); verwende, einmal in der Funktion und einmal beim Aufruf, kann das sein?
Vielen Dank!,
lgchar text[] = {"TAF LOWS TEMPO BKN"}; // File für mapping einlesen char * text_ptr = strtok (text, " "); while(text_ptr != NULL) { printf("%s\n", text_ptr); char translated[70]; getTranslation(mapping, text_ptr, translated); printf("%s\n", translated); text_ptr = strtok (NULL, " "); printf("Das ist es %s\n", text_ptr); } return (EXIT_SUCCESS); } void getTranslation(char mapping[], char encrypted[], char translated[]) { printf("Wie oft"); translated[0] ='\0'; char * pch = strtok (mapping, "\n"); while (pch != NULL) { if (strncmp (pch, encrypted, strlen (encrypted)) == 0) sscanf (pch, "%*[^=]%*c%[^\n]", translated); pch = strtok (NULL, "\n"); } if(strlen(translated) == 0) // wenn die Übersetzung nicht möglich ist das Original zurückgeben strcpy(translated, encrypted); }
-
Generic1 schrieb:
Hallo,
Danke für die Antwort, ich hab jetzt versucht, das zu machen (unten), leider wird getTranslation nur einmal aufgerufen, ich vermute weil ich 2 mal strtok (NULL, " "); verwende, einmal in der Funktion und einmal beim Aufruf, kann das sein?
Ja, das ist der Grund. Du könntest es mit Arrays von "Strings" realisieren und dann die Liste mit einer Schleife durchlaufen:
char * text[] = {"TAF", "LOWS", "TEMPO", "BKN"};
Du solltest dann aber die gesamte Liste der Funktion übergeben (inkl. Anzahl der Elemente), ansonsten kann es zu Komplikationen kommen. Vermeide auch, wenn möglich, die
getTranslation
Funktion mehrmals mitmapping
als Argument aufzurufen, da diese Zeichenkette nach Benutzung vonstrtok
unbrauchbar wird (sie wird von der Funktion verändert).
-
Hallo,
vielen Dank für die Antwort, hat mir sehr geholfen, war gestern schon fast am verzweifeln :(,
Hab das mit dem char[][]- Array schon gemacht, hatte aber gestern immer noch das Problem, das nicht alles mit der Methode getTranslation übersetzt wurde, das liegt wahrscheinlich an den Bug von strtok, den Du mir geschickt hat ->
mapping[] wird verändert und daher klappt die Übersetztung nicht.Wäre es möglich, mapping immer vor dem Aufruf von strtok zu kopieren (deep copy) und dann erst getTranslation zu übergeben. Ich hab momentan keine Idee, wie ich das machen soll, dass ich getTranslation nur einmal aufrufe.
Wie kann man in C ein char- Array am Besten kopieren.Besten Dank,
lg
Generic
-
Die Funktion
getTranslation
könnte bei jedem Aufrufmapping
intern kopieren. Du musst Dir aber noch Gedanken über die Speicherung machen: Ein Array fester Größe odermalloc
benutzen. Wennmapping
keine feste Größe hat, dann ist wohlmalloc
die richtige Wahl.Hier mal ein Beispiel:
void getTranslation (char mapping[], char encrypted[], char translated[]) { char *pch, *map; translated[0] = '\0'; map = malloc (strlen (mapping) + 1); // '\0' nicht vergessen! if (!map) return; strncpy (map, mapping, strlen (mapping)); map[strlen (mapping)] = '\0'; pch = strtok (map, "\n"); while (pch != NULL) { if (strncmp (pch, encrypted, strlen (encrypted)) == 0) sscanf (pch, "%*[^=]%*c%[^\n0]", translated); pch = strtok (NULL, "\n"); } if (strlen (translated) == 0) // wenn die Übersetzung nicht möglch ist das Original zurückgeben strcpy (translated, encrypted); free (map); }
-
Besten Dank,
funktioniert wurderbar,
lg aus Salzburg,
Generic1