char *zeigerfeld



  • hi, ich habe volgendes programm geschrieben, der sinn ist eigentlich
    dass ich zeilen aus einer datei einlesen will und dass dann jede zeile in einem zeiger char *k gespeichert werden soll.
    z.b.
    k[1]="hausmann"
    k[2]="boot"

    #include <iostream>
    #include <string>
    #include <fstream>
    using namespace std;
    
    class lesen {
        private:
        char *filename;
        string errortext;
        int zeilen;
        char *k;
    
        public:
        lesen():filename(0),zeilen(0){k=new char[50]; /*k[1]="hh";*/}
        ~lesen() { }
        void setfilename(char *f) { filename=f;}
        void cfile();
    };
    
    void lesen::cfile() {
        ifstream in(filename);
        string tmp;
        if (!in) {
            errortext="Konnte Datei nicht oeffnen";
            exit(1);
        }
        while (getline(in,tmp,'\n')) {
            zeilen++;
            cout << tmp<< endl;
        }
    }
    
    int main(void)
    {
        lesen *l;
        l=new lesen;
        l->setfilename("Bildschirmausdruck.txt");
        l->cfile();
        return 0;
    }
    

    das problem ich den kommentar entferne (gruen) erhalte ich folgende fehlermeldung:
    error: invalid conversion from `const char*' to `char'

    ich weis jetzt nur nicht, was ich überladen muss dafuer...



  • char *k = new char[50];
    

    du hast speicher allokiert für 50 chars, und der zeiger ka zeit aufs erste!

    bspw:

    k[x]
    

    zeigt nun auf das ZEICHEN mit dem index x! d.h. du kann nur EIN zeichen im index speichern, aber du willst ein string speichern ! das geht nicht:)

    k[0]='A'; Zeichen OK
    k[0]="AA" ; String FEHLER (Ist ja nur platz für EIN ZEICHEN)

    Lösung_

    char **k = char*[10]; //Pointer Array; Platz für 10 Strings
    
    for(int i=0; i< 10; ++i)
      k[i]= new char [50];
    

    nun kannst du damit arbeiten wie du es vor hattest

    k[0]= "hausmann";
    

    P.S: Speicher freigeben nich vergessen

    P.P.S: Nimm einen

    std::vector< std::string > k;
    

    als alternative



  • vielen dank dir

    jetzt wo du es gesagt hast, ist es mir auch klar geworden mit dem einem char.

    danke



  • Und das: void setfilename(char *f) { filename=f;} sollte man tunichts vermeiden. Du lässt filename auf einen dir unbekannten Bereich zeigen! Was passiert wenn der Array auf den f zeigt nach dem Aufruf von setfilename wieder freigegeben wird?

    void setfilename(char *f) { filename=f;}
    
    void set_filename(const char* filename)
    {
        std.:size_t len = std::strlen(filename) + 1;
        m_filename = new char[len];
        std::strcpy(m_filename, filename);
    }
    


  • Ehm ich war "deviloper" und "(D)Evil_not at home" ...

    #include <iostream>	// std::ostream&
    #include <fstream>	// std::ifstream
    #include <vector>	// std::vector
    #include <string>	// std::getline
    #include <cstring>	// std::strlen, std::strcpy
    // NIE im Header using-Direktive verwenden
    
    class read_file
    {
    private:
    	char*	m_filename;				// entweder komplett char* oder komplett std::string, 
    									// damit du aber deine Fehler verstehst ... dieses
    									// Mal komplett mit char* gearbeitet.
    	std::vector<char*> m_content;	// Wird jetzt umständlich da wir char* statt std::string
    									// nutzen, aber du sollst ja den elementaren Umgang mit 
    									// Zeigern dabei lernen. std::vector ist ein dynamischer 
    									// Array
    
    public:
    	read_file() : m_filename(NULL) {}
    	read_file(const char* filename, bool read) { set_filename(filename); if (read == true) read_data();}
    	~read_file() 
    	{ 
    		delete [] m_filename;		// Was wir einmal anfordern müssen wir wieder freigeben.
    									// delete [] NULL ist laut Standard auch erlaubt.
    		for (std::vector<char*>::iterator it = m_content.begin(); it != m_content.end(); ++it) 
    									// Einmal den kompletten vector durchinterrieren.
    			delete [] (*it);		// Den beanspruchten Speicher wieder freigeben.
    	}
    
    	void set_filename(const char* filename)
    	{ 
    									// Wir wollen nicht das unser m_filename außerhalb des von uns
    									// kontrollierten Bereiches liegt. D.h. es niemand uns zwischen-
    									// durch zerstören kann.
    		m_filename = new char[std::strlen(filename) + 1];	// Einen Array, mit Platz für soviele
    															// Zeichen die bis zum nächsten '\0' in
    															// filename stecken.
    		std::strcpy(m_filename, filename);		// Und kopieren ...
    	}
    
        void read_data()
    	{
    		std::ifstream in_file(m_filename);
    		if (!in_file)
    			throw std::invalid_argument("invalid filename");	// C++ hat exceptions ...
    		char data[1024];			// Wir geben einfach eine maximale Größe
    									// von 1023 vor (data[1024 - 1] = 0!)			
    		while (std::getline(in_file, data, '\n', 1023))
    		{
    			m_content.push_back(NULL);
    			m_content.at(m_content.size() - 1) = new char[std::strlen(data) + 1];
    			std::copy(m_content.at(m_content.size() - 1), data);
    		}
    	}
    
    	friend std::ostream& operator << (std::ostream& out, const read_file& data)
    	{
    		std::vector<char*>& content = data.m_content;
    		for (std::vector<char*>::iterator it = content.begin(); it != content.end(); ++it)
    			out << (*it) << "\n";
    	}
    };
    
    int main()
    {
    	std::cout << read_file("Bildschirmausdruck.txt", true) << std::endl;
    }
    

    ... ließ dir mal durch ob du alles verstehst ... sollte aber soweit so alles stimmen. Ist aber nicht getestet .


Anmelden zum Antworten