Verkettete Listen.
-
Hi Community!
Ich habe ein Problem mit einer Verketteten Liste. Die Aufgabe ist es, eine csv-Datei einzulesen und in eine verkettete Liste zu speichern. Einlesen kann das Programm, jedoch liest es komischerweise den letzten Eintrag zweimal ein. Mein zweites Problem ist für euch wahrscheinlich lächerlich aber: Wie kann ich die Elemente dann der Reihe nach ausgeben. In meinem Programm gibt es nur den letzten Eintrag aus, diesen dafür mehrmals.
Hier mal mein Code:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct CSVData { char * data; CSVData *next; }; typedef struct CSVData CSV; CSV *daten = NULL; int main(int argc, char *argv[]) { CSV *node, *old; FILE *fptr = NULL; char input[255]; fptr = fopen("db.csv", "r"); do { fgets(input, 255, fptr); getchar(); if(input) { CSV *node = new CSV; printf("tt.%s ", input); node->data = input; node->next = daten; daten = node; printf("ttt.%s", daten->data); } }while(!feof(fptr)); fclose(fptr); printf("a.%s", daten->data); daten = daten->next; printf("b.%s", daten->data); #ifdef WIN32 printf("\n"); system("PAUSE"); #endif return 0; }Die csv-Datei ist Standard, sprich in der Form "string;string;string;..."
Ich bitte um Verbesserungen wenn möglich. Danke schonmal in voraus

-
Moin.
Benutz doch zum Ausgeben der verketteten Liste auch eine while-Schleife. Oder meinst Du was anderes mit Elemente ausgeben?
-
Nein wir meinen schon dasselbe. Ich habe es zuerst mit einer While-Schleife versucht, bin jedoch gescheitert und habe es daher vereinfacht, sprich ohne While-Schleife versucht. Müsste doch ebenso gehen oder nicht?
-
So, nun habe mein Programm auf Vordermann gebracht. Hier nochmals der Code.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> using namespace std; struct CSVData { char *data; struct CSVData *next; }; void printstruct(struct CSVData*); struct CSVData *link0r = NULL; int main() { FILE *f = fopen("db.csv", "r"); while(!feof(f)) { char *input = new char; fscanf(f,"%s",input); printf("1\n"); struct CSVData *node = new struct CSVData; printf("2\n"); cout << "node-addr.: " << node << endl << "input-addr.: " << &input << endl; getchar(); strcpy(node->data,input); printf("3\n"); cout << node->data << endl; delete input; node->next = link0r; printf("4\n"); link0r = node; cout << link0r->data << endl << endl << endl; }; cout << "bla" << link0r->data; //printstruct(link0r); #ifdef WIN32 printf("\n"); system("PAUSE"); #endif return 0; } void printstruct(struct CSVData *anfang) { struct CSVData *zeiger = anfang; printf("||=====================================" "==================||\n"); while(zeiger != NULL) { printf("%s\n", zeiger->data); printf("|-----------------------------------" "----------------------|\n"); zeiger=zeiger->next; } }Jetzt hab ich nurmehr das Problem mit der Ausgabe. Die Prozedur printstruct sollte den Inhalt der verketteten Listen ausgeben, tut es aber nicht. Irgendwelche konstruktiven Vorschläge? Wenn möglich noch heute - Danke.
-
Ein paar Spontanitäten:
1. Du benutzt inkonsistent C und C++ (scanf ist C, besser cin, new ist C++)
2. Du allokierst EIN Zeichen für input, liest aber dann eine ganze Zeichenkette ein -> potentieller Absturz
3. Du kopierst input mit strcpy (wieder C statt C++) in ein Datum für das kein Speicher allokiert wurde (node->data ist ein nackter Zeiger, kein Array)
4. "Tut es aber nicht" ist keine Beschreibung des Fehlers. Das Programm sollte eigentlich garnicht bis dahin kommen. Falls doch -> Glück
-
@LordJaxom:
Was ist eigentlich das entsprechende C++ Equivalent zu strcpy (mal davon abgesehen, dass man sowieso std::string nehmen sollte^^).
-
1. Du benutzt inkonsistent C und C++ (scanf ist C, besser cin, new ist C++)
2. Du allokierst EIN Zeichen für input, liest aber dann eine ganze Zeichenkette ein -> potentieller Absturz
3. Du kopierst input mit strcpy (wieder C statt C++) in ein Datum für das kein Speicher allokiert wurde (node->data ist ein nackter Zeiger, kein Array)
4. "Tut es aber nicht" ist keine Beschreibung des Fehlers. Das Programm sollte eigentlich garnicht bis dahin kommen. Falls doch -> Glück@LordJaxom:
Zu 1. Ja, dass ich inkonsistent C und C++ benutze ist mir klar und by the way: ich benutze fscanf (nicht scanf) - weiß nicht obs da eine C++ Alternative gibt oder ob fscanf eh schon C++ ist.
Zu 2. Ich habe mal versucht char *input = new char[255] aber dann stürzte das Programm ab. Speicherzugriffsfehler.Könntest du mir (oder jemand anderes) bitte den Code ausbessern? Stehe wirklich an.
PS.: Dass ich inkonsistent C und C++ verwende liegt daran, weil ich die letzten 2 Jahre in der Schule nur C gelernt habe und heuer einen neuen Lehrer bekommen habe und daher die Mischung. Sorry ich weiß, dass es nicht gut ist so zu programmieren.

-
Hallo SeniiX,
z. B. so:
#include <iostream> #include <string> #include <fstream> #include <deque> // A struct to hold the words in a line. struct Line { std::deque< std::string > words; }; int main() { // A double ended queue for an arbitrary // number of lines in the text-file std::deque< Line* > lines; // Open the file and and check its open std::ifstream ifile( "test.txt" ); if ( ifile.is_open() ) { // As long as we did not reach the end of // the file, read the file line by line while ( !ifile.eof() ) { std::string temp; std::getline(ifile, temp); // Now, split each line in the substrings // separated by the character ';' and store // them in a new Line structure Line* line = new Line; std::basic_string< char >::size_type front = 0, back = 0; while ( back != temp.npos ) { // Get the next separating character back = temp.find( ";", front ); // Get the substring and store it in the Line struct line->words.push_back( temp.substr( front, back - front ) ); // Make the position one post the separating // caracter the new begin of the next search front = back + 1; } // store the new Line in the lines queue lines.push_back( line ); } // The file is not needed anymore, so close it ifile.close(); } else std::cout << "Unable to open file!!" << std::endl; // Write the input to the screen int count = 1; for ( std::deque< Line* >::iterator i = lines.begin(); i != lines.end(); ++i, ++count ) { std::cout << "Words in line " << count << ':' << std::endl; for ( std::deque< std::string >::iterator j = (*i)->words.begin(); j != (*i)->words.end(); ++j ) std::cout << *j << std::endl; std::cout << std::endl; } // Clean up for (std::deque< Line* >::iterator i = lines.begin(); i != lines.end(); ++i) delete *i; }Das verwendet anstatt einer Liste eine "double ended queue" aus der STL, aber die kannst Du ja leitcht ersetzen...
Viele Grüße
Knecht