bAdVamp Geschrieben 20. Juni 2002 Teilen Geschrieben 20. Juni 2002 Hallo, ich hab leider ein Problem. Ich muss aus einer Textdatei zeilenweise Datensätze auslesen und in ein zweidimensionales Array ablegen (zur späteren Sortierung und Auswertung). Da es sich immer um andere Textdateien handelt, kann ich voerher nicht angeben, wie groß das Array wird, weiss aber dass eine Zeichenkette ca 150 Stellen hat. Beim Aufruf in der Sortierung brauch ich allerdings beide Indizes -> datensatz[j] Frage: Wie muss ich den Arraypointer deklarieren? char *datensatz[150] ? :confused: Einleseschleife: while((datensatz=fgets(fplesen))!=EOF) { ... datensatz++; } Kann ich dann auf datensatz[5][100] zugreifen? Oder bin ich da komplett auf'm Holzweg? :eek: Gibt's 'ne FAQ, in der ich sowas finde. Die Beispiel-Listings arbeiten immer mit festgelegten Arrays... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TingleTangle Geschrieben 20. Juni 2002 Teilen Geschrieben 20. Juni 2002 Also so auf die schnelle kann ich dir nur sagen, dass du fuer die groesse des Arrays malloc() benutzen solltest. Ich kenn aber auswendig die Syntax nicht, also lass ich Versuche. Auf was soll der Zeiger zeigen, auf einen Datensatz, oder auf ein einzelnes Element. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 20. Juni 2002 Autor Teilen Geschrieben 20. Juni 2002 Der Zeiger soll auf ein zweidimensionales Array zeigen von dem ich den ersten Index nicht festlegen kann, nur den zweiten...Ein Datensatz soll dann mit datensatz[j] angesprochen werden können. bis jetzt hab ich mir des so gedacht: main (int argc, char **argv) { int i, x; char *datensatz[150]; FILE *fplesen; FILE *fpschreib; if((fplesen=fopen(argv[1],"r"))==NULL) //Öffnen der zu lesenden Datei { printf("Fehler beim Oeffnen der Datei %s \n\n", argv[1]); getche(); goto Ende; //Abbruch } else { if((fpschreib=fopen(argv[2],"a"))==NULL) //Öffnen der Ausgabedatei { printf("Fehler beim Oeffnen der Zieldatei %s \n\n", argv[2]); getche(); goto Ende; //Abbruch } else { if((datensatz=malloc(104857600))==NULL) { printf("Fehler: mangelnder Speicherplatz!\n\n"); getche(); goto Ende; //Abbruch } else { //----------AUSLESEN UND AUSGEBEN DER DATEIEN-----------------------------------------------// while((datensatz=fgets(fplesen))!=EOF) { ... if(datensatz[j]='\t') { } } } } } fcloseall(); Ende:; } Kann ich das Array so als zweidimensionales ansprechen? Erkennt "C" was ich will? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 20. Juni 2002 Autor Teilen Geschrieben 20. Juni 2002 Also besser gesagt, soll der Zeiger eigentlich nur helfen, die Datensätze(Strings) die aus einer Textdatei zeilenweise ausgelesen werden, in ein Array zu stopfen, wobei der erste Index den Datensatz angibt und der zweite das Zeichen des eingelesenen Strings. Damit ich in jeden beliebigen Datensatz jedes beliebige Zeichen zur weiteren Verarbeitung aussuchen kann... Das Problem ist halt nur, dass ich nie weiss, wie viele Datensätze(=Zeilen in der Textdatei) ich auslesen und als Zeichenkette speichern muss. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hoppo Geschrieben 20. Juni 2002 Teilen Geschrieben 20. Juni 2002 Probiers mal so: main() { char *Pointer; Pointer = new char[100][50]; // oder zur Laufzeit: Pointer = new char[i][j]; //danach kannste ihn wie ein Array behandeln // aber nicht vergessen des Speicher wieder frei zu geben delete Pointer; } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maddin Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 ich würde als zeiger so ein kontrukt verwenden: char** pArray = new [50][150]; später mit delete [] pArray; wieder löschen Dann kannst du damit wie mit einem normalen Array arbeiten. Also z.B.: pArray[0][15] = 'h'; Dafür musst dir bloß bekannt sein, wieviele Zeilen die Datei hat um das Array in der entsprechenden Größe zu erstellen. Dagegen helfen zwei Wege. 1.) Vorhereinmal die Zeilen in der Datei 'durchzählen' oder 2.) mit malloc und realloc arbeiten. Davon kenne ich aber die genau Syntax nicht. Hilft wahrscheinlich ein Blick in die MSDN. ps: Wenns ein wenig C++ sein darf hilft dir vielleich auch ein std::vector<char*> weiter. Beispiel: #include <vector> #include <fstream.h> main() { std::vector<char*> vDaten; fstream fIn("text.txt", ios::in); while (!fIn.eof()) { char* szTmp = new char[201]; fIn.getline(szTmp, 200); vDaten.insert(vDaten.end(), szTmp); // Syntax: ??? } // ... } [/PHP] Der Vector bietet einem dann glaube ich auch noch ein paar Methoden zum sortieren an. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Woodstock Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 Ich finde das mit einem Array alles in allem sehr schwer zu lösen. Ich würde dabei auf eine verkettete Liste zurückgreifen. Da braucht man dann auch nur den Platz den man wirklich braucht. Bine Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eight Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 Was sit eigentlich gegen folgende Lösung einzuwenden: char** pCharArray = NULL; pCharArray = (char**)malloc(sizeof(char*)); Das ganze kannst du dann wie gewohnt füllen ( pCharArray[0] = "String"; ) und du bist völlig ungebunden was die Länge eines Strings sowie die Anzahl der Datensätze angeht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 24. Juni 2002 Autor Teilen Geschrieben 24. Juni 2002 sowas ähnliches hab ich versucht: #define MAX_ZEILENLAENGE 150 typedef char datensatz[MAX_ZEILENLAENGE + 1]; datensatz *zeilen = NULL; int anzmaxzeilen = 1; int anzzeilen = 0; char *c; zeilen = malloc(anzmaxzeilen * sizeof(datensatz)); das hatte aber einen Speicherzugriffsfehler zur Folge, da das mit der Typdef mit Array wohl so nicht geht, konnte der Speicher nicht berechnet werden Das mit dem Füllen ist wieder so eine Sache. Ich lese aus einer Textdatei zeilenweise aus. Eine Zeile hat ca. 150 Zeichen, nur die Anzahl der Zeilen ist immer verschieden und es muss nach bestimmten Spalten der Zeile (durch Tabs getrennt) sortiert werden, daher brauch ich unbedingt die dynamische Speicherverwaltung. Und ich muss das Array mit beiden Indizes ansprechen können -> blabla[j] Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Goos Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 Kannsts ja mal so in der Art probieren.....musst das natuerlich n bissl umbasteln und entsprechende Funktionen schreiben, sonst ists ne Menge schreibarbeit denk ich char** pCharArray = NULL; pCharArray = (char**)malloc(sizeof(char*)); pCharArray[0] = (char*) malloc(150 * sizeof(char)); pCharArray[0][0]= 'a'; //mal so zum Test pCharArray = (char**)realloc(pCharArray, _msize(pCharArray) + sizeof(char*)); //erweitern um eins pCharArray[1] = (char*) malloc(150 * sizeof(char)); pCharArray[1][0]= 'b'; //mal so zum Test printf("%c", pCharArray[0][0]); printf("\n%c", pCharArray[1][0]); free(pCharArray[0]); free(pCharArray[1]); free(pCharArray);[/PHP] Goos Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Goos Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 Es waer allerdings vielleicht geschickter, zwecks Initialisierung fuer die 150er Arrays calloc anstelle von malloc zu verwenden denk ich mir Goos Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 24. Juni 2002 Autor Teilen Geschrieben 24. Juni 2002 wo genau liegt da der Unterschied? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Goos Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 Naja mit malloc haettest von der Sytntax her malloc(150 * sizeof(char)) und bei calloc waers denn calloc(150, sizeof(char)) *g* :OD Der wirkliche Unterschied ist, aber dass bei calloc alle 150 Elemente mit 0 initialisiert werden, bei malloc muesstest das dann noch von hand machen, dass nicht irgendein ******* drinsteht. Goos Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eight Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 Hi, die Speicherzugriffsverletzung resultiert vielleicht aus einem fehlendem cast. Da die Funktion 'malloc' eine Zeiger vom Typ void zurückgibt, muß man diesen in den benötigten Datentyp umwandeln. Bsp.: zeilen = (datensatz*)malloc(anzmaxzeilen * sizeof(datensatz)); Dann sollte es klappen. Und das mit dem einlesen sollte eigentlich auch klappen. Bsp.: ( Quasi Pseudo Code; kein Anspruch auf syntaktische Fehlerfreiheit; dient nur der Anschauung ) ) int i = 0; while( !EOF ) { pCharArray = file.ReadString(); i++; } Der Zugriff auf die einzelnen Zeichen funktioniert dann reibungslos mit: char cAnything = pCharArray[m][k]; (m gibt dann denn jeweiligen DS an und k das jeweilige Zeichen) Wie das mit dem Sortieren vor sich gehen soll hab ich allerding noch nicht aus deinen Ausführungen entnehmen können. Soll nach dem Einlesen aller DS sortiert werden oder sofort während des einlesens? Gibt es dazu eine GUI oder ist das ganze Teil einer Bibliothek? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 24. Juni 2002 Autor Teilen Geschrieben 24. Juni 2002 Die Sortierung muss ich leider auch selbst schreiben, k.A. ob's da schon was Fertiges gibt... Eine Zeile besteht aus 9 durch Tabs getrennte Spalten (d.h. die Spalten entstehen eben, wenn man die ~100.000 Zeilen untereinanderstehen hat). Dann soll nach der 3. Spalte sortiert werden und die jeweils dazugehörige 7. Spalte mit erfasst werden zwecks späteren Aufaddierens. Genauso muss nochmal die 5. Spalte sortiert werden und wieder die 7. mit extrahiert werden. Also werd ich erst sortieren können, wenn alle Zeilen erstmal irgendwo abgelegt sind, oder geht das auch einfacher? Für jeden Hinweis, der mir großartiges Schleifengepopel erspart, bin ich dankbar... Eigentlich brauch ich von jeder Zeile nur den Abschnitt nach dem 2. Tab, dem 4. Tab und dem 6. Tab. Ich denk mir schon, dass ich die Sache ziemlich kompliziert angehe, aber ich soll ja schliesslich was lernen bei, ne :confused: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Goos Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 Dann solltest meiner Meinung nach wohl beim einlesen auch wirklich nur die 3 Teile rausholen und die dann vielleicht in dein 3D Array schreiben. So in der Art pCharArray[Zeile][Tab-Abschnitt][inhalt] . Ansonsten muesstest ja beim sortieren alles tausendmal nach Tabs durchsuchen Goos Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 24. Juni 2002 Autor Teilen Geschrieben 24. Juni 2002 Ich hab auch schon überlegt, ob ich nicht einfach die Datei VOR dem Einlesen in die drei Teile zerhacke, bzw. alles andere rausschmeisse und dann mit nem Bash-Befehl mir die Anzahl der Zeilen ausgeben lasse, die ich dann wiederum im Kommandozeilenaufruf als Parameter mitgeb... und mir damit mein Array festlege: datensatz[argv[4]][150] Is halt net so elegant aber wohl funktional... Allerdings hab ich überhaupt keinen Blassen wie ich beim Einlesen bereits die drei Abschnitte herausfiltern kann. Ich dachte, dazu müsste ich die gesamte Textdatei eben erst mal irgendwohin einlesen und nach Tabs druchsuchen, dann wieder durchkämmen und auslesen dann nochmal zum sortieren *arghl* Wie muss das denn aussehen, wenn ich z.B. mit: while((datensatz=fgets(fplesen))!=NULL) { ... } die Textdatei auslesen will? Oder empfiehlst Du mir von vorneherein eine andere Einleseroutine? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Goos Geschrieben 24. Juni 2002 Teilen Geschrieben 24. Juni 2002 also mit while(!feof( fplesen ) ) { fgets(datensatz, 150, fplesen); test = strchr( datensatz, '\t' ); result = test - datensatz + 1;[/PHP] haettest dann z.B. die position des ersten Tabs ermittelt. Das brauchst dann ja nur entsprechend fuer die weiteren Tabs machen und dann kannst den Text zwischen den Tabs gleich in die richtigen Arrays kopieren. Goos Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 25. Juni 2002 Autor Teilen Geschrieben 25. Juni 2002 Hi, gaaaaaaaaanz dickes Danke erstmal für die C-Schulung, die ich hier fleissig in Anspruch nehme !!! Leider gips noch'n kleines Problem : Ich muss das auf einer Linux-Kiste zum Laufen kriegen, da funktioniert die _msize() leider nicht. Gibt's eine Funktion, speziell für Linux, mit der man dasselbe erreicht? Gruß, ]bAd[Vamp Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Goos Geschrieben 25. Juni 2002 Teilen Geschrieben 25. Juni 2002 Soweit ich das weiss gibts bei Lunix keine Substitution dafuer Ist das jetzt schlimm? *g* Man braucht dieses msize() ja auch nicht, aber ich finds halt praktisch Goos Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 25. Juni 2002 Autor Teilen Geschrieben 25. Juni 2002 Ich hab da schon was gefunden, allerdings is des kein Spass das jetzt wieder einzubauen :eek: http://utopia.ision.nl/users/nico/tools/c/memtrace/ *arghl* Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Goos Geschrieben 25. Juni 2002 Teilen Geschrieben 25. Juni 2002 Nuja das ist halt auch nix standardmaessiges und wie schon gesagt du brauchst das msize ja in diesem Falle auch gar nicht zwingend Goos Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 25. Juni 2002 Autor Teilen Geschrieben 25. Juni 2002 Braucht's das nich, um festzustellen, wo der Zeiger grad steht? Wie kann ich das umgehen, wenn ich die Speichererweiterung so machen will pCharArray=(char**)realloc(pCharArray, _msize(pCharArray)+sizeof(char*)); ? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Goos Geschrieben 25. Juni 2002 Teilen Geschrieben 25. Juni 2002 Brauchen tust das da wirklich nicht. msize ist ja wie der name schon halbwegs sagt die Groesse des bisher allokierten Speichers....da du das aber zuvor eh selbst gemacht hast, weisst du ja wieviel das ist D.h. du kannst auch vom malloc angefangen und dann bei jedem realloc einfach nen zaehler mitlaufen lassen. Am obigen Beispiel waer das dann sowas in der Art char** pCharArray = NULL; int zaehl = 1; pCharArray = (char**)malloc(sizeof(char*)); pCharArray[0] = (char*) malloc(150 * sizeof(char)); pCharArray[0][0]= 'a'; //mal so zum Test zaehl++; pCharArray = (char**)realloc(pCharArray, zaehl * sizeof(char*)); //erweitern um eins zaehl ++; pCharArray[1] = (char*) malloc(150 * sizeof(char)); pCharArray[1][0]= 'b'; //mal so zum Test printf("%c", pCharArray[0][0]); printf("\n%c", pCharArray[1][0]); free(pCharArray[0]); free(pCharArray[1]); free(pCharArray);[/PHP] Goos Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bAdVamp Geschrieben 25. Juni 2002 Autor Teilen Geschrieben 25. Juni 2002 Na ho, jetzt hab ich's kapiert...Danke Ich hoffe, Du fährst nicht in Urlaub die nächsten Tage.... Gruß, ]bAd[Vamp Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.