Wie auf lokale Iteratoren außerhalb einer Funktion explizit zugreifen? + Zusatz...



  • Hallo,

    ich habe eine Klasse mit mehreren Funktionen, ich möchte in einer Funktion auf die Iteratoren einer anderen Funktion zugreifen, sie sollen jedoch nicht global sein. Gibts da einen Weg? Wie mache ich das am besten? So sieht meine Klasse im Moment aus...:

    class Editor
    {
    public:
    
    	//Textdatei einelesen
    	void einlesen(){
    
    		std::ifstream ifs("C:/asci1.txt");
    		std::string tmp;
    
    		typedef std::vector<std::string> linevector;
    
    		linevector lv;
    
    		linevector::iterator li;
    
    		while(getline(ifs, tmp)) 
    		{
    			lv.push_back(tmp);
    			tmp = std::string();
    		}
    
    	}
    
    	//Bestimmte Zeilen ansehen
    	void viewline(){
    
    		typedef std::vector<int> intvector;
    
    		intvector intv;
    		intvector::const_iterator inti;
    		intvector::iterator intii;
    
    		std::cout<<"Welche Zeilen sollen ausgegeebn werden?: \n\n";
    
    		int eingabe;
    
    		while (std::cin >> eingabe && eingabe != 999 )
    		{
    		intv.push_back(eingabe);	
    		}
    
    		for (inti=intv.begin(); inti!=intv.end(); ++inti) 
    		{
    			li = lv.begin() + *inti; //Iteratoren von außen
    			std::cout << *li << std::endl;
    		}
    	}
    
    };
    
    int main(){
    
    	Editor edit;
    	edit.einlesen(){
    	edit.viewline();
    	return 0;
    }
    

    Vielen Dank im vorraus



  • Stichwort: Parameter



  • hab schon etwas rumprobiert.. aber wenn ich versuche die Parameter so

    void viewline(linevector::iterator li, linevector lv)
    

    zu übergeben ist das natürlich syntakisch falsch... 😕



  • Zuerst mußt du einmal den Datentyp 'linevector' in der Klasse bekannt machen (nicht nur in der Funktion).
    Außerdem solltest du dann hiervon ein Klassenmember anlegen, denn sonst ist der 'linevector' nach dem Aufruf der Methode 'einlesen' wieder gelöscht.

    Dann könntest du einen Iterator als Parameter benutzen:

    void viewline(typename linevector::iterator li)
    

    Die einfachere Art wäre aber einfach die Zeilennummern (Beginn und Ende) als int Werte anzugeben...



  • bin noch anfänger, hab grad mal etwas nach klassenmember gegooglelt, aber was das genau ist, ist mir nicht klar...

    ich hab nun die deklarationen aus der funktion rausgezogen und global gemacht:

    public:
    
    	typedef std::vector<std::string> linevector;
    	linevector lv;
    	linevector::iterator li;
    
    	//Textdatei einelesen
    	void einlesen(){
    

    und die viewline funktion um die parameter erweitert:

    void viewline(typename linevector::iterator li, typename linevector lv){
    

    doch dann meckert der compiler:

    .\ViewLines.cpp(35) : error C2899: typename cannot be used outside a template declaration
    .\ViewLines.cpp(35) : error C2899: typename cannot be used outside a template declaration
    .\ViewLines.cpp(68) : error C2660: 'Editor::viewline' : function does not take 0 arguments
    

    und wie sollte ich es als int übergeben? ich brauche ja den vector und den iterator der einlese-funktion...



  • Hallo travelflo22,

    wenn Du den linevector lv als Datenmember erzeugst brauchst Du keinen iterator darauf zu übergeben. Du kannst ihn Dir dann in der Funktion viewline neu holen.

    class Editor
    {
    public:
        typedef std::vector<std::string> linevector;
    
        //Textdatei einelesen
        void einlesen()
        {
            std::ifstream ifs("C:/asci1.txt");
            std::string tmp;
    
            linevector::iterator li;
    
    		while(getline(ifs, tmp)) 
            {
                lv.push_back(tmp);
                tmp = std::string();
            }
    
        }
    
        //Bestimmte Zeilen ansehen
        void viewline()
        {
            typedef std::vector<int> intvector;
    
            intvector intv;
            intvector::const_iterator inti;
    
            std::cout<<"Welche Zeilen sollen ausgegeebn werden?: \n\n";
    
            int eingabe;
    
            while (std::cin >> eingabe && eingabe != 999 )
            {
                intv.push_back(eingabe);    
            }
    
            linevector::iterator li;
            for (inti=intv.begin(); inti!=intv.end(); inti++) 
            {
                li = lv.begin() + *inti; //Iteratoren von außen
    			std::cout << *li << std::endl;
            }
        }
    
    private:
        linevector lv;
    };
    

    Ich hoffe das hilft Dir weiter.

    Viele Grüße
    Knecht



  • danke.. das hat mir sehr weitergeholfen...



  • nachdem ich hier soviel Hilfe erfahren hab bräuchte ich nochmal ne Idee...

    ich habe eine Funktion geschrieben, welche bestimmte zeilen aus einem string-vector (welchre Zeilen enthält) löschen soll... wenn ich jedoch das löschen über eine for-schleife lassen, wird durch das ständige erneute aufrufen der funktion lv.erase(li) das eregbnis verfälscht, da die Elemente ja nachrücken...

    meine Idee wärs nun nen neuen Vecotor zu erstellen, und abzufragen ob ein Wert rein darf oder nicht, aber das erscheint mir als zu umständlich.. gibts für diesen fall einen kürzeren Weg?

    So siehts bis jetz aus:

    //Löschen
    	void removeline()
        {
            typedef std::vector<int> intvector;
    
            intvector intv;
            intvector::const_iterator inti;
    
            std::cout<<"Welche Zeilen sollen geloescht werden?: \n\n";
    
            int eingabe;
    
            while (std::cin >> eingabe && eingabe != 999 )
            {
                intv.push_back(eingabe);    
            }
    
            linevector::iterator li;
            for (inti=intv.begin(); inti!=intv.end(); inti++)
            {
                li = lv.begin() + *inti; //Iteratoren von außen
                lv.erase(li);
    
            }
    
    		 for (li=lv.begin(); li!=lv.end(); li++)
    		 {
    			 std::cout << *li << std::endl;
    		 }
    


  • Ne Möglichkeit wäre die zu löschenden Elemente mit einer bestimmten Zahl zu überschreiben und dann nachher alle Elemente mit dieser Zahl zu löschen ...



  • In einem anderen thread gab es die Frage schon einmal:
    erase gibt den neuen Iterator zurück

    it = lv.erase(it);
    


  • Eventuell kannst du auch std::remove_if verwenden - nämlich dann wenn du die "entfernen ja oder nein?" Bedingung als Predicate definieren kannst welches als Parameter eben nur den String bekommt.



  • Th schrieb:

    In einem anderen thread gab es die Frage schon einmal:
    erase gibt den neuen Iterator zurück

    it = lv.erase(it);
    

    Aber die Elemente werden trotzdem verschoben und die Positionsangaben im vector würden nicht mehr stimmen... Oder sehe ich da was falsch ???


Anmelden zum Antworten