Problem beim öffnen eines Verzeichnisses



  • ich habe da ein kleines problem.
    ich uebergebe einer funktion ein char * also genau das, was eigentlich die funktion opendir haben moechte.
    das unguenstige an dieser sache ist nur, dass das nicht funktioniert

    ermittelt wird der pfad mit der funktion:

    char* getEntry(){	
    	char a,atmp[30];	
    	int i = 0,iReturn;
    	vector<string> myvec;	
    
    	do{	
    		iReturn = 0;
    		clearscreen();		
    		cout << "Eingabe:" << atmp;		
    		initscreen();	
    		a = getch();						
    		endwin();							
    
    		atmp[i] = a;				
    
    		i++;				
    
    	}while(a != RETURN);
    	return atmp;	
    }
    

    liest mir das verzeichnis aus:

    vector<string> loadDir(char * dir){
    	DIR * pdir;
    	struct dirent *pent;
    	vector<string> direct;		
    
    	pdir=opendir(dir); //"." refers to the current dir
    
    	if (!pdir){
    		printf ("Fehler beim öffnen des Verzeichinsses");
    		exit(1);
    	}
    	errno=0;
    	while ((pent=readdir(pdir))){		
    		direct.push_back(pent->d_name);		
    	}
    	if (errno){
    		printf ("Fehler beim lesen des Verzeichnisses");		
    		exit(1);
    	}
    	closedir(pdir);
    	return direct;
    
    }
    

    es wird auch alles wunderbar von der getEntry-funktion zu loadDir-funktion uebergeben...aber das wars auch schon.
    wenn ich jetzt aber zb.: eine zuweisung dir = "." mache, oder welchen gueltigen pfad auch immer funktioniert der ganze spuck wieder.
    wuerd mich freuen, wenn jemand mir einen tipp geben koennte was hier falsch laeuft



  • Hallo,

    char* getEntry(){
    char a,atmp[30];
    [...]
    return atmp;

    Ups! Du gibst eine Referenz auf eine lokale Variable zurück (das sollte dir dein Compiler allerdings eigentlich auch schon mitgeteilt haben).
    Nach Verlassen von getEntry löst sich aTmp in Schall und Rauch auf. Jeder nachfolgende Zugriffsversuch ist Leichenfledderei und wird mit undefiniertem Verhalten bestraft.



  • mein fehler bei der formatierung ... derzeit hab es beim formatieren fuerden beitrag versehentlich da hineingegeben ...
    atmp ist derzeit global definiert



  • Hallo,
    poste doch bitte einfach mal eine kompilierbare Minimalversion die dein Problem verdeutlicht. In deinem geposteten Code ist nämlich so einiges fragwürdig (atmp wird ausgegeben obwohl es uninitialisert ist, atmp ist am Ende nicht null-terminiert...)



  • das sollte es sein.
    das fehler drinnen sind und das einiges nicht passt ist klar, da es ja ein test ist.

    #include <iostream>
    #include "ncurses.h"
    #include <vector>
    #include <errno.h>
    #include <dirent.h>
    using namespace std;
    
    int const RETURN = 13;
    
    char atmp[30];
    void clearscreen();
    void initscreen();
    vector<string> loadDir(char* dir);
    char* getEntry();
    
    int main(){	
    
    	char * selEntry;
    	vector<string> myvec;
    
    	selEntry = getEntry();			
    
    	myvec = loadDir(selEntry);	
    
    	cout << sizeof(myvec) << endl;
    
    }
    
    char* getEntry(){	
    	char a;	
    	int i = 0,iReturn;
    	vector<string> myvec;
    
    	do{	
    		iReturn = 0;
    		clearscreen();		
    		cout << "Eingabe:" << atmp;		
    		initscreen();	
    		a = getch();						
    		endwin();												
    
    		atmp[i] = a;
    
    		switch(a){
    			case BACKSPACE:
    				cout << BACKSPACE << endl;
    				cout.flush();
    			break;
    			case SPACE:
    				cout << endl <<  "SPACE" << endl;
    			break;
    
    		}			
    
    		i++;				
    
    	}while(a != RETURN);
    	return atmp;	
    }
    
    vector<string> loadDir(char * dir){
    	DIR * pdir;
    	struct dirent *pent;
    	vector<string> direct;		
    
    	pdir=opendir(dir); //"." refers to the current dir
    
    	if (!pdir){
    		printf ("Fehler beim öffnen des Verzeichinsses");
    		exit(1);
    	}
    	errno=0;
    	while ((pent=readdir(pdir))){		
    		direct.push_back(pent->d_name);		
    	}
    	if (errno){
    		printf ("Fehler beim lesen des Verzeichnisses");		
    		exit(1);
    	}
    	closedir(pdir);
    	return direct;
    
    }
    
    void clearscreen(){
    	cout << "\033[2J\n\n";
    	return;
    }
    
    void initscreen(){
    	initscr();
    	cbreak();
    	noecho();
    	nonl();
    	keypad(stdscr,TRUE);
    	return;
    }
    


  • hat sich geklaert das problem...am ende des pfades war ein leerzeichen und das hat mich in teufelskueche gebracht



  • Hätte auch eine kurze Frage zur opendir-Funktion.
    Undzwar benutze ich diese unter C++ mit Strings, ich rufe sie derzeit folgendermaßen auf:

    string vname = "irgendwas";
    DIR *dirp;
    dirp = opendir(vname.c_str());
    

    Das heisst, opendir versucht, das Verzeichnis "irgendwas" aufzurufen. So, und hierauf bezieht sich meine Frage:
    Wenn ich das aktuelle Verzeichnis öffnen will, muss ich ja nur "." angeben. Muss ich bei Verzeichnissen innerhalb des aktuellen dann sowas wie ".unterverzeichnis" oder "./unterverzeichnis" angeben?



  • TheBrain schrieb:

    Muss ich bei Verzeichnissen innerhalb des aktuellen dann sowas wie ".unterverzeichnis" oder "./unterverzeichnis" angeben?

    "unterverzeichnis" sollte genügen "./unterverzeichnis" kann nicht schaden
    Kurt



  • Ok, danke.
    Das Verzeichnis-Öffnen scheint zu klappen. Aber das Auslesen der Dateien darin macht Probleme:
    Es liegt nur eine Datei darin, er findet jedoch noch zwei weitere mit den Namen "." und ".."
    Wie kann ich die Suche nun auf diese eine richtige Datei beschränken?

    Ich kopiere hier mal ein wenig meines Codes hinen:

    string vname = "irgendwas";
        DIR *dirp = opendir(vname.c_str())
        struct dirent *dir_entry;    
    
            while((dir_entry = readdir(dirp)) != NULL)
            {
                cout << dir_entry->d_name << endl; // Schleife scheint 3 Mal durchlaufen zu werden, Ausgaben: ".", "..", "datei.cde"
                string open_term = vname + "/" + dir_entry->d_name;
    
                ifstream data;
                data.open(open_term,ios::in);
                    ...
    

    Hier meckert der Compiler übrigens auch, dass das erste Argument von open() falsch sei ... schreibe ich den String direkt rein, meckert er nicht oO



  • diese zwei dateien gibt's in jedem verzeichnis
    "." zeigt auf sich selbst
    ".." zeigt aufs übergeordnete Verzeichnis.
    Wie wärs damit ?

    string vname = "irgendwas";
        DIR *dirp = opendir(vname.c_str())
        struct dirent *dir_entry;    
    
        while((dir_entry = readdir(dirp)) != NULL)        {
           string dirname( dir_entry->d_name );
           if ( dirname != "." && dirname != ".." ) {
              cout << dirname << endl; 
              string open_term = vname + "/" + dirname;
    
              ifstream data;
              data.open(open_term.c_str(),ios::in);
    

    Kurt



  • Jawohl, mir kam die Erleuchtung kurz nach Verfassens meines letzten Beitrags, sorry. Habs im Prinzip genau so gemacht, wie du es vorschlägst, nur dass ich die If-Bedingung umgedreht hab, d.h.

    if(dir_entry->d_name == "." || dir_entry->d_name == ".." || dir_entry->d_type != DT_REG)
      continue;
    

    Und klar, im open-Aufruf habe ich wie immer mal wieder das c_str() vergessen.
    VIelen Dank, jetzt klappt es wonderbra! 🙂



  • TheBrain schrieb:

    Jawohl, mir kam die Erleuchtung kurz nach Verfassens meines letzten Beitrags, sorry. Habs im Prinzip genau so gemacht, wie du es vorschlägst, nur dass ich die If-Bedingung umgedreht hab, d.h.

    if(dir_entry->d_name == "." || dir_entry->d_name == ".." || dir_entry->d_type != DT_REG)
      continue;
    

    Und klar, im open-Aufruf habe ich wie immer mal wieder das c_str() vergessen.
    VIelen Dank, jetzt klappt es wonderbra! 🙂

    Und das funktioniert bei dir ?.

    Hint: du vergleichst pointer wenn du direkt dir_entry->d_name vergleichen willst dann hilft strcmp().
    Kurt


Log in to reply