Strings begrenzt?



  • Du machst dir das Leben unnötig schwer! Du solltest Zeiger nur dann benutzen, wenn es wirklich nötig ist und einen vernünftigen Grund dazu gibt 🙄

    👎



  • Joa ok, werd es demnächst dann lassen, aber wie lös ich nun mein Problem.^^



  • Wenn die Datei Unicode Daten enthält, dann solltest du wstring statt string verwenden. wstring ist zwar auch nicht toll, aber besser als string. Und schreib den COde neu, ohne unnötige new.



  • Es gibt zu Unicode auch einen guten und informativen Artikel im Magazin: Einführung zu Codepages und Unicode

    Und zu Heap vs Stack: Abgesehen davon, dass sie langsamer ist, führt manuelle Speicherverwaltung oft zu Speicherlecks. Das Anfordern und wieder-Freigeben ist lästig, mehr Tipparbeit und Fehleranfällig; kurz: "rofl" hat Recht, Zeiger nur verwenden, wenn man sie wirklich braucht 😉 Und dann gibt es noch wesentlich bessere Möglichkeiten als rohe Zeiger, z.B. die Schlauen Zeiger.



  • Ok, hab das Problem jetzt einiger Maßen gelöst.
    Nur ein Problem hab ich noch, das ganze dauert eine Ewigkeit, gibt es keine schnellere Methode, den Inhalt einer Datei in eine Variable einzulesen?^^
    Ich lese nämlich jedes Zeichen einzeln aus und hänge diese auch einzeln an den String.^^

    Hier meine Lösung bisher:

    string tpath = "C:\\db.rar";
    	boost::filesystem::path p(tpath);
    	unsigned long size = boost::filesystem::file_size(p);
    	wfstream f(tpath.c_str(),ios::in|ios::binary);
    	wstring str;
    	while(!f.eof())
    	{
    		wchar_t buf;
    		f.read(&buf,1);
    		str += buf;
    	}
    	f.close();
    	wfstream f2;
    	f2.open("C:\\real.txt",ios::out|ios::binary);
    	f2.write(str.c_str(),str.size()-1);
    	f2.close();
    


  • naja schau halt wie groß die file ist und dann mach nen entsprechend großen buffer wo du die datei als einen block reinladest



  • 1. Eine Textdatei mit dem Flag "binary" auszulesen oder zu schreiben ist ziemlich ziemlich dumm.
    2. Bei "read" kannst du doch sogar angeben, wieviel gelesen auf einmal werden soll.
    3. Ich denke es wäre besser, wenn du die Stream-Operatoren benutzt. Wieso willst du den Text eigentlich in einem String, spräche was gegen std::vector<std::wstring> ?



  • die kürzeste methode zum laden einer datei in den speicher (als string), die mir einfällt, geht so:

    std::ostringstream tmp;
    tmp << file.rdbuf();
    

    kommt aber darauf an, was du vorhast. eventuell wird dir dann ein kopieren in einen std::string nicht erspart bleiben. dann könntest du dir auch überlegen, nicht einen std::vector<wchar_t> als puffer zu nehmen, à la:

    std::vector<wchar_t> buffer(file_size);
    file.read(&buffer[0], file_size);
    

    wenn deine datei allerdings riesig wird, wäre es wahrscheinlich nicht sinnvoll, ihren gesamten inhalt gleichzeitig im speicher zu halten.

    ps. wie gesagt, brauchst du tatsächlich ios::binary ?



  • du kannst ja mit so weit ich weiß readline die einleseblöcke vergrößern.

    zum anderen Problem:
    Wenn du deine Variablen gleich wieder löschen möchtest, weil du sie nicht mehr brauchst, kannst du dass auch auf dem Stack, und zwar mit Blöcken {} also einfach vor der variabelerstellung '{' und wenn du sie nicht mehr brauchst '}'.



  • @Badestrand es ist ja keine Textdatei, sondern irgend eine Datei, die ich reinlade, und leider wird der ganze Inhalt nur über ios::binary geladen.

    Ich will die Datei in einen String laden, weil ich grad an einer kleinen Socketklasse arbeite.

    Ich erstelle beispielsweise ein Objekt File, welche ich dann rübersende.

    Client c("127.0.0.1",123456,AF_INET);
    File f("C:\\what.ever");
    SRObject<File> o(f);
    c.send(o);
    

    Neben dem Fileobjekt soll es dann noch andere Objekte wie Command, Information, usw. geben.

    Ich meine ja nur, dass ich den Inhalt der Datei, so oder so irgendwann mal in den Speicher laden muss, um ihn zu verschicken, wieso soll ich ihn dann net gleich in das Objekt als String laden, oder sollte ich doch lieber einen Container verwenden?^^

    Ahja hier noch der aktuelle Code meiner File.load:

    bool File::load(const string& p)
    		{
    			this->setPath(p);
    			path pa(p);
    			this->setSize(file_size(pa));
    			wfstream f(p.c_str(),ios::in|ios::binary);
    			wstring source;
    			while(!f.eof())
    			{
    				wchar_t buf;
    				f.read(&buf,1);
    				if(!f.eof())
    				source += buf;
    			}
    			f.close();
    			if(source.size()!=this->_size)
    				return 0;
    			this->setSource(source);
    			return 1;
    		}
    

    EDIT: Grad ist mir in den Sinn gekommen, dass es wirklich nicht so vorteilhaft sein würde, wenn ich vllt ein paar Gigabyte im Speicher hätte...

    Vielleicht mach ich das wirklich mit Containern, die immer nur einen Teil des Codes im Speicher verwalten, wenn dieser gesendet wurde, wird ein neuer Teil geladen und dieser gesendet usw.

    Könnte wohl etwas komplexer werden.^^



  • Oha, das bringt doch einiges Licht ins Dunkel 😉

    Aaaaalso, es ist durchaus verständlich, dass du die ganze Datei in den Speicher laden willst. Völlig unverständlich ist mir nur, warum du einen String nimmst und es ein Unicode-String sein muss.

    Normalerweise nimmt man für Puffer sowas:

    char* buf = new char [ file_size ];
    f.read( buf, file_size );
    delete[] buf;
    

    Meinetwegen kann der Zeiger noch hinter einem Smart-Pointer stecken, das ist aber nicht der Punkt. Ein Unicode-String ist deshalb schon nicht geeignet, weil dort 2 Bytes pro "Zeichen" benutzt werden -> die Datei verbraucht im Speicher also doppelt soviel Platz wie auf der HDD. Und einen String generell zu benutzen, nunja, da dürften sich die Geister scheiden. Zum einen ist es aber definitiv nicht die Aufgabe eines Strings, Binärdaten herumzukarren, zum anderen ist ein String völliger Overkill, da du quasi keine seiner Funktionen benötigst.



  • deshalb nimmt man in so einem fall std::vector<char> (s.o.) 🙂



  • Leicht OT:

    markusrw schrieb:

    Nope, aber wieso nicht, wenn ich die Variablen nur kurz brauch, verwende ich halt den Heap und lösch sie dann auch wieder bequem aus den Heap. ;P...

    Äh - gerade wenn man sie nur kurz braucht, ist der Weg über den Heap viel zu aufwendig (Lauf- und Programmierzeit ) und "speicherleckanfällig"....
    Der Heap hat seine Stärke gerade in der Langlebigkeit seiner Objekte.

    Gruß,

    Simon2.



  • Badestrand schrieb:

    Aaaaalso, es ist durchaus verständlich, dass du die ganze Datei in den Speicher laden willst. Völlig unverständlich ist mir nur, warum du einen String nimmst und es ein Unicode-String sein muss.

    Normalerweise nimmt man für Puffer sowas:

    char* buf = new char [ file_size ];
    f.read( buf, file_size );
    delete[] buf;
    

    Ich dachte, ab Windows NT wird nur noch mit Unicode gearbeitet, deshalb hab ich daraus geschlussfolgert, dass alle Dateien auf Unicode aufgebaut sind.^^
    Dass Unicode doppelt so viel Speicher verbraucht war mir auch klar.

    Aber, falls ich mich geirrt habe, dann werd ich natürlich nur char nehmen, und meint ihr, ich soll vllt immer nur 1/10 der Datei ins Speicher laden, es senden, dann das 2. Zehntel usw., ich weiß net, ob das umbedingt schneller geht, aber wenn ich somit net den ganzen PC terminiere, ist das schon besser _

    EDIT: ok, hab grad über einen Hexeditor das ganze Zeug angeschaut und ist doch nicht Unicode, danke für den Tipp, wäre net schön gewesen, doppelt so viel zu versenden ;P



  • markusrw schrieb:

    Ich dachte, ab Windows NT wird nur noch mit Unicode gearbeitet, deshalb hab ich daraus geschlussfolgert, dass alle Dateien auf Unicode aufgebaut sind.^^

    Unicode ist ja nur eine Darstellungs-/Speicherart für Zeichen von Text. Binärdateien enthalten aber einfach irgendwelche Bytes, deren Bedeutung durch das Dateiformat festgelegt sind.

    markusrw schrieb:

    Aber, falls ich mich geirrt habe, dann werd ich natürlich nur char nehmen, und meint ihr, ich soll vllt immer nur 1/10 der Datei ins Speicher laden, es senden, dann das 2. Zehntel usw.

    Kannst ja einfach immer Stücke der Größe 1 MB oder so in den Speicher laden und versenden. Wenn die Datei nur 1 KB groß ist und du die in 10 Stücken einliest, ist das auch wieder nicht gut 😉


Anmelden zum Antworten