C++ /// Datei inklusive Leerzeichen einlesen?

Gruß Thomas!

Grand Admiral Special
Mitglied seit
27.03.2008
Beiträge
2.027
Renomée
118
Standort
Bayreuth
  • Docking@Home
Die Frage steht oben, ich kriegs nicht fertig, mit f.open() die Leerzeichen mit einzulesen, die gehen immer verloren, da er aufhört einzulesen nach einem Leerzeichen
 
PHP:
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <windows.h>
#include <io.h>
#include <sys/stat.h> 

using namespace std;


int main()
{
   char * nick;
   cout<<"Geben Sie Ihren neuen Nick ein!\n";
   cin>>nick;
   FILE * pFile;
   char mystring [100];
   pFile = fopen ("config.cfg" , "r+");
   if (pFile == NULL) perror ("Error opening file");
   else {
        do{
             fgets(mystring, 100, pFile);
             puts(mystring);
             }
             while(strcmp(mystring, "name \"Player\"\n")!=0);                  
             puts(mystring);
   }
   fclose(pFile);
   system("PAUSE");
                  
}

Soweit bin ich jetzt gekommen (includes bitte nicht beachten xD).

Finden tut er schon mal, das was ich will.

Jetzt möchte ich nur noch das, was er findet editieren, wie geht das?
 
Zuletzt bearbeitet:
Du speicherst es in ner TXT und editiert sie?! *buck*
 
Ich versteh nicht ganz, was du meinst. Die Datei existiert bereits und da drin steht schon was!
 
Ich versteh nicht ganz, was du meinst. Die Datei existiert bereits und da drin steht schon was!
Der wollte dich auf den Arm nehmen.
Es gibt verschiedene Ansätze Dateien zu manipulieren. Der wohl einfachste ist es
die Datei komplett ein zu lesen, im Speicher zu verändern und wieder komplett neu zu schreiben/überschreiben. Hier sollte man sich im klaren sein, dass das nur bis zu einer bestimmten Dateigröße (!Speicher!) funktioniert. Es gibt zahlreiche Editoren die so arbeiten, oder dann spezielle Editoren, die direkt auf der Festplatte arbeiten können.
Zunächst ein paar Kommentare zu deinem Code:
Code:
char * nick;
cout<<"Geben Sie Ihren neuen Nick ein!\n";
cin>>nick;
ACHTUNG, du schreibst hier irgendwo in den Speicher. Ich empfehle dir eine ordentliche IDE damit du auf solche Fehler von Anfang an achtest.
Vielleicht solltest du auch einheitlich C oder C++ include Bibliotheken verwenden und nicht alles mischen wie es passt.
So noch ganz Quick&Dirty eine mögliche Lösung:
Code:
// editconfig.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

const char* FILE_NAME = "config.cfg";
const unsigned int BUF_LEN = 15;

void readFile(string name, vector<string> &buffer);
void writeFile(string name, vector<string> &buffer);

int _tmain(int argc, _TCHAR* argv[])
{
	string filename = FILE_NAME;
	string nick;
	cout<<"Geben Sie Ihren neuen Nick ein!\n";
	cin >> nick;
	vector<string> filebuffer;
		// filebuffer: Speicher für Dateiinhalt Zeilen werden als Strings in einem vector gespeichert
	vector<string>::iterator zeile;
		// zeile: als iterator zum Zugreifen auf einzelne Zeilen aus dem filebuffer Vektor

	readFile(filename,filebuffer);

/* Ausgabe der eingelesenen Datei
    for(zeile = filebuffer.begin(); zeile != filebuffer.end(); zeile++) {  
			cout << (*zeile) << endl;
		}
*/
/* bearbeite Datei */
    for(zeile = filebuffer.begin(); zeile != filebuffer.end(); zeile++)
	{  
		if ( (*zeile).find("name \"Player\"") != string::npos )
		{
			(*zeile).clear();
			(*zeile).append( "name \"" ).append( nick ).append( "\"" );
		}
	}
/**/
/* Ausgabe der bearbeiteten Datei
    for(zeile = filebuffer.begin(); zeile != filebuffer.end(); zeile++) {  
			cout << (*zeile) << endl;
		}
*/
	writeFile(filename,filebuffer);

	return 0;
}

void readFile(string name, vector<string> &buffer)
{
	char _buf[BUF_LEN];                     // buffer zum einlesen der datei
	fstream fs(name.c_str(), ios::in);         // filestream objekt zum einlesen einer datei

	if (!fs.bad())
	{//keine Fehler, Datei fertig zum lesen
		string _line;
			// _line: enthält die aktuelle zeile bis zur leseposition
		while(!fs.eof())
		{//Dateiende nicht erreicht, weiter lesen
			string _str;
				// _str: enthält ein Fragment der aktuellen Zeile
			fs.getline(&_buf[0],sizeof(_buf));
			_str.append(&_buf[0]);
			if( fs.fail() ) {
				if(_str.length() == 0) {
					//Ende der Zeile erreicht!
					fs.clear( ~ios::failbit & fs.rdstate());
					_line.append(_str);
					buffer.push_back(_line);
					_line.clear();
				} else if (_str.length() == (sizeof(_buf) - 1) ) {
					//noch nicht am Ende der Zeile
					fs.clear( ~ios::failbit & fs.rdstate());
					_line.append(_str);
				} else {
					//sonstiger Fehler
					cerr << "Fehler beim lesen" << endl;
					exit(1);
				}
			} else {
				//Ende der Zeile (zeile kürzer als buffer)
				_line.append(_str);
				buffer.push_back(_line);
				_line.clear();
			}
		}
		fs.close();
	}
}

void writeFile(string name, vector<string> &buffer)
{
	char _buf[BUF_LEN];                     // buffer zum einlesen der datei
	fstream fs(name.c_str(), ios::out);        // filestream objekt zum schreiben einer datei

	if (!fs.bad())
	{//keine Fehler, Datei fertig zum lesen
		vector<string>::iterator _line = buffer.begin();
		fs << (*_line++);
		if (_line != buffer.end()) {
			for(; _line != buffer.end(); _line++)
				fs << endl << (*_line);
		}
		fs.close();
	}
}
 
Hmmm, ich hab das Gefühl, dass ich das was du da schreibst nur ansatzweise versteh xD

Wie meinst du das mit irgendwo in den Speicher schreiben?

PHP:
   char nick[80];
   cout<<"Geben Sie Ihren neuen Nick ein!\n";
   cin.getline(nick, sizeof(nick));

Besser so?
 
Zuletzt bearbeitet:
Prima! Viel besser!!! Das davor war deswegen so kritisch weil du den Pointer nick nicht initialisiert hast, er daher irgendwo hin gezeigt hat (undefiniert). Bei ordentlichen Debug IDE´s werden sie meistens trotzdem initialisiert (zB mit 0xcccccccc, bei Zugriff auf diese Speicherzelle wird dann ein halt/stop des Programms und die Rückkehr zum Debugger eingeleitet).
In der neuen Version von dir initialisierst du nick mit der Adresse auf einen 80 Byte großen reservierten Bereich und erlaubst cin sogar nur diese 80 Byte zu verwenden. Längere Namen akzeptiert cin nicht, damit kann der Speicher auch nicht überschrieben werden. Nur bin ich mir jetzt nicht ganz sicher ob es bei cin.getline nicht sogar nur 79 Zeichen sein sollten. Müsste man mal testen was da wirklich im Speicher steht wenn man da einen 80 Zeichen Namen eingibt. Zeichenfolgen sollen halt immer null-terminiert sein.
 
Ich glaub das auch ;), dass er nur 79 Zeichen einliest, aber in meinem C++ Buch stands so beschrieben;), weil da müsset ja noch das \0 Zeichen dabei sein oder nicht?
 
Ganz blöde Frage, muss es wirklich C++ sein? Es gibt einige Sprachen, die gerade dafür wesentlich besser geeignet sind.
 
Ein char-Array von 80 Zeichen sind 79 Zeichen plus '\0'
char* nick ist ein nicht initialisierter Pointer also Teufelszeug und igitte bäh pfui.
Es sei denn man hat bei größeren Projekten Spaß an ausgiebigen Debugsitzungen.
Persönlich bevorzuge ich
char nick [80] = memset(nick,0,sizeof(nick));
Dann ist nicht nur der Pointer initialisiert, sondern das char[] hat einen definierten Inhalt
und endet auf '\0'.
Klasische Weichei-Programmmierung;D

Bisschen stört mich das "Mischen" von C und C++.
Wenn es sein muss, dann statt der C-Lib die Entsprechung nach ISO-Standard 1990.
Also für stdio.h -> cstdio.
Einfach mal die Doku durchgucken oder
http://www.cplusplus.com/reference
Ansonsten ist es eine Möglichkeit statt char[] string zu nehmen. Es ist die String-Klasse von Cpp.
Passt gut zu cin, cout und bietet jede Menge guter Methoden zum Stringhandling.
Ich finde diese Methoden besser als die Fnktionen aus cstring.h (aka string.h).
Anstatt char nick [80] also string nick;
Gruss
wori
 
Zuletzt bearbeitet:
char nick [80] = memset(nick,0,sizeof(nick));

char nick[80] = {0}; tuts auch ;)

oder

char nick [80];
memset(nick,0,sizeof(nick));

Ansonsten würde ich mir mal "new" und "delete" zu Gemüte führen. ;) Sonst stößt man da sehr schnell an Grenzen wenns um Dateien geht.
 
Zuletzt bearbeitet:
Stimmt das war Blödsinn.

Gemeint war natürlich:

char [80] nick;
memset(nick,0,sizeof(nick));

Und an new habe ich die ganze Zeit gedacht.
 
Zurück
Oben Unten