xtp file durchsuchen



  • Hi, habe fast alles fertig. Jedoch gibt es etwas was keinen Sinn ergibt.
    : Das Vorgehen:
    Die xtp wird gelesen. Danach suche ich nach dem zeichen < und kopiere die variable bis > in ordner. Danach suche ich die variable </ordner>. Ist diese Variable weiter weg als die gesuchte variable kopiere ich den ordner in path.

    Mein Problem:
    Füge ich cout oder for() ändert sich das Ergebnis. (( schaut ganz unten unter hier ))

    #include <stdafx.h>
    #include <iostream> // für Cout
    #include <fstream> // für Open
    #include <stdio.h>
    #include <conio.h> // für getchar
    #include <string>

    using namespace std;

    void main()
    {
    char variable[1000]; // zwischenspeicher für die gesammte xtp file
    char zeichen[1000]; //Zeiger auf xtp file
    int weiter=0; // Nur zum kopieren in den zwischenspeicher
    char ordner[100]; //gelesener Ordner
    int or=0,save=0;
    int größe;
    char zwischending[100]; //Einfügen von </ in denn Ordner
    string path; // Hier wird er path gespeichert

    // Lesen der xtp file
    FILE *fil;
    fil = fopen("c:\\xtp.xtp", "r");
    if (fil == NULL)
    {
    printf("\nDatei kann nicht geöffent werden\n");
    exit(-1);
    }

    while(!feof(fil))
    {
    weiter++;
    fscanf(fil, "%c", &zeichen);
    if (!feof(fil))
    //printf("%c", *zeichen);
    variable[weiter]=*zeichen;
    }
    variable[weiter]='\0';

    // Suche nach < in der xtp file und kopiere alles in ordner bis >
    for(int i=save;i<weiter;i++)
    {
    if(variable[i]=='<')
    {

    for(int b=i+1;b<weiter-i;b++)
    {
    if(variable[b]!='>')
    {
    ordner[or]=variable[b];
    or++;
    save++;
    }
    else{ ordner[or]='\0';break ;}
    }
    break;
    }
    }

    string gesammt(variable); //erzeugen der string von der gesammten xtp file
    cout <<gesammt;

    // Anladen er </
    größe = sizeof(ordner) / sizeof(int);
    zwischending[0]='<';
    zwischending[1]='/';

    for(int c=2;c<größe+2;c++)
    {
    zwischending[c]=ordner[c-2];
    } zwischending[größe+1]='>';
    string zwischendingg(zwischending);
    cout <<zwischendingg;
    // zwischending halt die die kodierung </Ordner>

    //gefundener ordner
    string ordnerr(ordner);
    cout <<"Der erste Ordner"<<endl;
    cout <<ordnerr<<endl;

    //suche nach </Ordner>
    int pos=gesammt.find(zwischendingg);
    printf("Ordner String %i\n",pos);

    //suche nach dem gesuchten string
    string gesuchterstring ="anfangswerte";
    int ges=gesammt.find(gesuchterstring);
    printf("Gesuchter String muss kleiner sein als Ordner %i\n",ges);

    //schauen ob der gesuchte string darunter liegt
    if(ges<pos)
    {
    path=ordnerr;
    }//else cout << "Der gesuchte String befindet sich nicht in "<<ordnerr<<endl;
    cout << "Der Path ist "<<path<<endl; // <---- SCHAUT HIER-----------

    fclose (fil);
    system("pause");
    };

    ps: um jetzt weiter zu machen müßte ich eine äußere schleife einbauen füge ich for (int i=0;i<1;i++) ändert sich das ergebniss ?????



  • habe auf geändert. Schaue wie ich weiter vorankomme. Wer verbesserungsvorschläge hat immer he damit.

    while(!feof(fil))
    {
    fscanf(fil, "%c", &zeichen);
    if (!feof(fil))
    //printf("%c", *zeichen);
    variable[weiter]=*zeichen;
    weiter++;
    }
    variable[weiter]='\0';



  • *palmface* möchtest du c++ programmieren oder willst du nicht doch lieber C programmieren? Der Code macht echt nicht glücklich.

    Du mixst C-printf mit c++ cout -> nicht gut. Besser alles cout...
    Du benutzt C-FILE anstelle von c++ STL fstream.

    Auf chars und Arrays sollte und kann man in c++ komplett verzichten...

    Den Rest habe ich mir nicht angeschaut. Ich denke das sind die Hauptgründe warum hier niemand einen Verbesserungsvorschlag macht, weil es schlicht sinnlos scheint. Nichts gegen dich, aber wir kennen den Grund "Jürgen Wolf".



  • ja bei mir ist erstmal c und c++ ein mix werde später daraus nur c oder c++ machen. Wollte zu erst alles mit fstream stream machen jedoch hatte ich das problem damit das ich nur mit strings arbeiten konnte.

    Jedoch mu0te ich von < bis > einlesen was ich nicht mit strings machen kann



  • Sicher kann man das mit string machen!

    http://www.cplusplus.com/reference/string/string/find/
    http://www.cplusplus.com/reference/string/string/substr/

    Suche "<" und suche ">",
    lese ein von position "<" bis länge ">" - "<"

    Warum sollte das nicht gehen?



  • ich wusste nichtr wie das geht



  • Hamster schrieb:

    ich wusste nichtr wie das geht

    Du kannst immer fragen :), wie gesagt es ist nicht dein Fehler, aber du solltest versuchen dein Programm mit den Mitteln von c++ zu schreiben.

    Ich hoffe du kannst mit den Tipps von oben dein Programm auf fstream string und cout umschreiben und die C-Code entfernen.

    Deshalb sagt ich ja, du solltest dir ein Buch über die STL besorgen. Wenn du weitere Hilfe brauchst, dann frag ruhig. Aber vermeide dieses Mischen komplett!

    EDIT: Und bitte verwende c/c++ Codetags!



  • Ok ich werde es versuchen umzusetzen.
    Frage mich gerade noch etwas:
    Nachdem ich einen ordner gefunden habe. Und mein gesuchter string auch noch sich in diesem befindet. Würde ich diesen string in path schreiben.
    Jedoch werden es mehrere Ordner sein und ich möchte so mehrere strings haben. Wie sollte ich das am besten machen.
    Der Ordner wird bei jeder schleife überschrieben.

    if(ges<pos)
    {
    	  path=ordnerr;
    
    }
    


  • Den Ordnerstring in ein vector schreiben.
    http://www.cplusplus.com/reference/stl/vector/

    std::string pfad;
    std::vector<std::string> pfade;
    pfad = "C:\...";
    pfade.push_back(pfad);
    

    So kannst du immer auf alle gefunden Pfade zugreifen.



  • sau geil , danke geht



  • so nun versuche ich es nur noch in c++ zu machen. Jedoch stehe ich wieder vor einer Wand.

    er findet bei mir das zeichen nicht, was habe ich falsch gemacht ?

    using namespace std;
    
    void main()
    {
    
        ifstream file;
        char     zeile[1024];
    	size_t found;
    
        file.open("c:\\test.xtp", ios::in);
    
        if (file.good())
        {
            // An den Anfang der Datei springen
            file.seekg(0L, ios::beg);
    
            while (! file.eof())
            {
                // Die Datei zeilenweise auslesen
                file.getline(zeile, 1024);
                cout << zeile << endl;
            }
        }
        else
        {
            cout << "Datei nicht gefunden." << endl;
        }
    
    	string str(zeile);
      found=str.find('<');
      if (found!=string::npos)
    	  cout << "gefunden in: " << int(found) << endl;
    
    system("pause");
    };
    


  • Es wäre günstiger, wenn du die eingelesenen zeilen in einen Vector speicherst, und dafür kein char verwendest. Mit deiner Lösung durchsuchst du nur die zuletzt eingelesene Zeile. benutze konsequent std::string und schieben die Zeilen in den Vector, dann durchsuche den gesamten Vector.

    EDIT: bei einer XML Datei würde in dann allerdings annehemn, dass du in jeder zeile das "<" findest... Eventuell solltest du gleich nach dem gesuchten "value=" suchen.



  • Du kannst das so machen (ungetestet):

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	vector<string> daten;			//Enthält alle zeilen aus der Datei
    
    	ifstream datei;					// Datei-Handle
    
    	datei.open("C:\\...", ios::in);	// Öffne Datei aus Parameter
    	if(!datei)
    	{
    		cout << "Die Datei kann nicht geoeffnet werden." << endl;
    	}
    	else
    	{
    		while (!datei.eof())			// Solange noch Daten vorliegen
    		{
    			string str;
    			getline(datei, str);		// Lese eine Zeile
    			daten.push_back(str);		//Zeilen in den Vector schieben
    
    			cout << str << endl;		// Zeige sie auf dem Bildschirm
    		}
    		datei.close();					// Datei wieder schließen
    
    		//mache etwas mit den Daten!!!!
    
    		for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) {
    			size_t found = (*i).find("<");
    			if (found!=string::npos)
    				cout << "Der String wurde gefunden an Position: " << static_cast<int>(found) << endl;
    			//mache was du willst
    		}
    	}
    
    	cin.get();
    	return 0;
    }
    


  • ich hoffe ich habe deinen code richtig verstanden. ( wäre nie drauf gekommen es so zu machen )

    -daten.at(i) geht leider nicht.
    - und str.substr (found) kann ich es nicht so einstellen das es nur bis zu found2 liest. lg und danke nochmal

    vector<string>  pfade;
    		string pfad;
    
            for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) {
                size_t found = (*i).find("<");
                if (found!=string::npos)
    			{
    				for(vector<string>::iterator b = daten.at(i); b != daten.end(); ++b)
    				{
    					size_t found2 = (*b).find(">");
    						  if (found2!=string::npos)  pfad = str.substr (found);/*Nur bis found2*/  pfade.push_back(pfad); 
    				}
                    cout << "Der String wurde gefunden an Position: " << static_cast<int>(found) << endl;
    			}
    


  • Du brauchst den Vector nicht zweimal durchlaufen.

    vector<string> pfade;        
    
    for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) {
                size_t found = (*i).find("<");
                size_t found2 = (*i).find(">");
                if (found!=string::npos)
                    cout << "Der String < wurde gefunden an Position: " << static_cast<int>(found) << endl;
    
                if (found2!=string::npos)
                    cout << "Der String > wurde gefunden an Position: " << static_cast<int>(found2) << endl;
                //mache was du willst
    
                string pfad;
                pfad = (*i).substr(found, found2 - found);
                pfade.push_back(pfad);
    
            } //hier nach mit pfaden machen was du willst
    

    EDIT: Da fehlt noch einige Sicherheit und du musst schauen ob das Ergebnis = der Erwartung entspricht, eventuell habe ich auch einen fehler drinne (ungetestet).
    EDIT: Man kann natürlich die letzten 3 zeieln auch so schreiben:

    pfade.push_back((*i).substr(found, found2 - found));
    

    oder auch alles in der klammer in eine Zeile o.O

    pfade.push_back((*i).substr((*i).find("<"), (*i).find(">") - (*i).find("<")));
    

    fehlt dann aber nur noch ein:

    if ((*i).find(">") !=string::npos && (*i).find("<") !=string::npos)
    

    So nun bin ich Amok gelaufen!



  • wuw sry die letzen zwei dinger sind noch lange nicht in meiner ligga ( leider )

    jedoch bekomme ich einen speicherfehler: in der zeile

    pfad = (*i).substr(found, found2 - found);
    

    bin mir nicht sicher woran es liegen könnte



  • keine Prüfung von found und found2 auf string::npos siehe letzter codeblock.

    if ((*i).find(">") !=string::npos && (*i).find("<") !=string::npos)
    

    ist das selbe wie:

    if (found !=string::npos && found2 !=string::npos)
    


  • Getestet:

    #include <iostream> 
    #include <fstream> 
    #include <vector> 
    #include <string> 
    
    using namespace std; 
    
    int main() 
    { 
        vector<string> daten;            //Enthält alle zeilen aus der Datei 
    
        ifstream datei;                    // Datei-Handle 
    
        datei.open("C:\\test.txt", ios::in);    // Öffne Datei aus Parameter 
        if(!datei) 
        { 
            cout << "Die Datei kann nicht geoeffnet werden." << endl; 
        } 
        else 
        { 
            while (!datei.eof())            // Solange noch Daten vorliegen 
            { 
                string str; 
                getline(datei, str);        // Lese eine Zeile 
                daten.push_back(str);        //Zeilen in den Vector schieben 
            } 
            datei.close();                    // Datei wieder schließen 
    
            //mache etwas mit den Daten!!!! 
    
    		vector<string> pfade;
    
    		for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) { 
    			if ((*i).find(">") !=string::npos && (*i).find("<") !=string::npos)
    				pfade.push_back((*i).substr((*i).find("<"), (*i).find(">") - (*i).find("<") + 1)); 
            } 
    		//hier mit pfaden machen was du willst
    
    		for(vector<string>::iterator i = pfade.begin(); i != pfade.end(); ++i) { 
    			cout << "Pfad: " << (*i).c_str() << endl;
    		}
    		/////////////////////////////////////////////
        } 
    
        cin.get(); 
        return 0; 
    }
    


  • genial, ich habe ein schlechtes Gewissen. Du hast den ganzen code in c++ für mich überschrieben. Und finde ihn 100 mal besser als meinen c code. Alles greift genau in einer über. Machst du das Beruflich ?



  • Hamster schrieb:

    genial, ich habe ein schlechtes Gewissen. Du hast den ganzen code in c++ für mich überschrieben. Und finde ihn 100 mal besser als meinen c code. Alles greift genau in einer über. Machst du das Beruflich ?

    Ist mehr als Hobby entstanden, ich begeistere mich dabei aber auch für andere Sprachen.


Anmelden zum Antworten