[C++] std::String in const char konvertieren

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
X0r
Beiträge: 2770
Registriert: 15.03.2007 21:47
Kontaktdaten:

Beitrag von X0r »

Welche IDE verwendest du eigentlich? Bin gerade dabei mir die Visual C++ Express Editon zu installieren. Was kostenlose IDE's angeht soll es angeblich die beste sein.

Hier zu finden:
http://www.microsoft.com/germany/Expres ... press.aspx

Ansonsten vielleicht noch Code::Blocks. Aber taugt die was?
Ich benutze die Visual Studio IDE( also Visual C++ 2008 Express). Bin damit sehr zufrieden.
Benutzeravatar
X0r
Beiträge: 2770
Registriert: 15.03.2007 21:47
Kontaktdaten:

Beitrag von X0r »

Nun nochmal zurück zur IntToConstChar-Sache. Hatte erst folgende Funktion geschrieben:

Code: Alles auswählen

const char* IntToCChar(int a){
stringstream b;
string c;
b << a;
c=b.str();
return c.c_str();
}
Müsste ja eigentlich funktionieren, dem war aber nicht so. Hab immer nen leeren String bekommen.

Hab dann was anderes ausprobiert:

Code: Alles auswählen

const char* IntToCChar(int a){
stringstream b;
string c;
b << a;
c=b.str();
char* test;
test=new char[c.size()+1];
strcpy(test,c.c_str());
return test;
}
Und dieser code funktioniert wiederrum. Kann mir mal einer erklären, wieso?!

Ich bekomm echt ne Krise. :evil:
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

versuch es mal so :

Code: Alles auswählen

#include <sstream>
#include <string>
#include <iostream>

std::string IntToString(int a)
{
	std::stringstream strs;

	strs << a;

	return strs.str();
}

int main()
{
	int a = 42;

	std::cout << IntToString(a).c_str();
	
	return 0;
}
Benutzeravatar
X0r
Beiträge: 2770
Registriert: 15.03.2007 21:47
Kontaktdaten:

Beitrag von X0r »

Ja, das geht auch, aber wieso funktioniert der obige code nicht?
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Beitrag von milan1612 »

Weil c_str() einen Pointer auf den internen Buffer des Strings zurückgibt, und dieser
wird beim Verlassen der Funktion bei der Zerstörung des Strings gelöscht. Schönes Beispiel
für eines der häufigsten Probleme in C++...

In deinem zweiten Code funktioniert das weil du ja den Inhalt des Strings kopierst
bevor er zerstört wird. Allerdings hast du dann ein Memoryleak weil du ja den
mit 'new' angelegten Speicher nicht mehr freigibst (mit delete[] str;)...
Zuletzt geändert von milan1612 am 14.02.2009 13:46, insgesamt 1-mal geändert.
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Beitrag von milan1612 »

X0r hat geschrieben:Hm,
irgendwie kommt mir C++ gerade wie Chinesisch vor. Lange nix mehr gemacht, alles verlernt...

Es geht darum, dass ich eine Datei lesen will, in der sowohl Strings, als auch Integers gespeichert sind. Kann man ja mit der ifstream klasse auslesen, aber wie funktioniert das, wenn der inhalt gemischt ist(halt mal string, mal integer, mal float etc.)?

Code: Alles auswählen

			myfile->getline(test,sizeof(test));
			myfile->read(reinterpret_cast<char*>(&version),sizeof(int));
geht irgendwie nicht.
Zeig doch mal den Dateiinhalt und erklär was du damit machen willst.
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Benutzeravatar
X0r
Beiträge: 2770
Registriert: 15.03.2007 21:47
Kontaktdaten:

Beitrag von X0r »

Ne, hat doch geklappt.
Naja, ich poste dann mal hier den Code, kannst mir ja sagen, obs da irgendwelche Mängel gibt:

Code: Alles auswählen

string IntToString(int a){
	stringstream b;
	string c;
	b << a;
	c=b.str();
	return c;
}

string CharToString(char a){
	stringstream b;
	string c;
	b << static_cast<int>(a);
		c=b.str();
	return c;
}

string GetPathPart(const char* filen){
	int b=0;
	stringstream ftemp;
	string path,file;
	ftemp << filen;
	file=ftemp.str();
	
	for(unsigned int n=0;n<file.length();n++){
		if(file.substr(file.length()-n,1)=="/" || file.substr(file.length()-n,1)=="\\"){
			b=n;
			break;
		}
	}
	path=file.substr(0,file.length()-b+1);
	return path;
}




struct Surface{
	BBObject  id;
	int materialid;
};


class app
{
private:
	BBObject camera;

public:

	void Init(){
		bbBeginBlitz3D();
		bbGraphics3D(1024,768,0,2);
		bbSetBlitz3DTitle("TMF example","");
		this->camera=bbCreateCamera();
		bbCameraClsColor(this->camera,255,255,255);
	}


	BBObject LoadTMF(const char* file){
		BBObject mesh,csurf;
		string line,normalstr,filepath,texfile,nmap;
		int major=0,minor=0,surfaces=0,vertices=0,verts=0,t1=0,t2=0,t3=0,tris=0,matid=0,materials=0,r=0,g=0,b=0;
		float x,y,z,u,v,nx,ny,nz,alpha,shininess;
		char normals,sphr,alphamap;
		vector<Surface> surflist;
		vector<Surface>::iterator surfit;

		filepath="D:\\";

		ifstream *myfile=new ifstream;
		myfile->open(file,ios::binary);
		

		if(myfile->is_open()){

			bbColor(255,255,255);
			getline(*myfile,line);
			myfile->read(reinterpret_cast<char*>(&major),sizeof(int));
			myfile->read(reinterpret_cast<char*>(&minor),sizeof(int));
			myfile->read(&normals,sizeof(char));
			myfile->read(reinterpret_cast<char*>(&surfaces),sizeof(int));

			mesh=bbCreateMesh();
			
				for(int n=1;n<surfaces+1;n++){
				csurf=bbCreateSurface(mesh);

				myfile->read(reinterpret_cast<char*>(&vertices),sizeof(int));
				

	

				//read vertexes
				for(int k=0;k<vertices;k++){
					myfile->read(reinterpret_cast<char*>(&x),sizeof(float));
					myfile->read(reinterpret_cast<char*>(&y),sizeof(float));
					myfile->read(reinterpret_cast<char*>(&z),sizeof(float));
					bbAddVertex(csurf,x,y,z);
				}
				
				//read texture coordinates
				for(int k=0;k<vertices;k++){
					myfile->read(reinterpret_cast<char*>(&u),sizeof(float));
					myfile->read(reinterpret_cast<char*>(&v),sizeof(float));
					bbVertexTexCoords(csurf,k,u,v,1,0);
				}

				//read normals
				if(normals==1){
					for(int k=0;k<vertices;k++){
						myfile->read(reinterpret_cast<char*>(&nx),sizeof(float));
						myfile->read(reinterpret_cast<char*>(&ny),sizeof(float));
						myfile->read(reinterpret_cast<char*>(&nz),sizeof(float));
						 bbVertexNormal(csurf,k,nx,ny,nz);
					}
				}

				myfile->read(reinterpret_cast<char*>(&tris),sizeof(int));
		
				//read triangles
				for(int k=0;k<tris;k++){
					myfile->read(reinterpret_cast<char*>(&t1),sizeof(int));
					myfile->read(reinterpret_cast<char*>(&t2),sizeof(int));
					myfile->read(reinterpret_cast<char*>(&t3),sizeof(int));
					 bbAddTriangle(csurf,t1,t2,t3); 
				}
		
				myfile->read(reinterpret_cast<char*>(&matid),sizeof(int));
				
				Surface surf;
				surf.id=csurf;
				surf.materialid=matid;
				surflist.push_back(surf);
				}

				//======================================================
				//materials
				//======================================================
	
				myfile->read(reinterpret_cast<char*>(&materials),sizeof(int));
				for(int m=0;m<materials;m++){
					getline(*myfile,texfile);
					texfile=texfile.substr(0,texfile.length()-1);
					getline(*myfile,nmap);
					nmap=nmap.substr(0,nmap.length()-1);
					myfile->read(&sphr,sizeof(char));
					myfile->read(reinterpret_cast<char*>(&alpha),sizeof(float));
					myfile->read(reinterpret_cast<char*>(&shininess),sizeof(float));
					myfile->read(&alphamap,sizeof(char));
					myfile->read(reinterpret_cast<char*>(&r),sizeof(int));
					myfile->read(reinterpret_cast<char*>(&g),sizeof(int));
					myfile->read(reinterpret_cast<char*>(&b),sizeof(int));
					texfile=GetPathPart(file)+texfile;
	

					BBObject tex,nrmtex;
					if(alphamap==1){
						alphamap=2;
					}

					if(sphr==0){
						tex=bbLoadTexture(texfile.c_str(),alphamap);
					}
					else{
						tex=bbLoadTexture(texfile.c_str(),64+alphamap);
					}

					if(nmap!=""){
						nmap=GetPathPart(file)+nmap;
						nrmtex=bbLoadTexture(nmap.c_str(),alphamap);
					}
					
					BBObject brush=bbCreateBrush(255,255,255);
					bbBrushAlpha(brush,alpha);
					bbBrushColor(brush,r,g,b);
					bbBrushShininess(brush,shininess);
	
					if(nmap!=""){
						bbTextureBlend(nrmtex, 4); //Dot3-Bumpmap-flag
						bbTextureBlend(tex, 5);
						bbBrushTexture(brush,nrmtex,0,0);
						bbBrushTexture(brush,tex,0,1);
						bbBrushFX(brush,2);
					}
					else{
						bbBrushTexture(brush,tex,0,0);
					}



					for(surfit=surflist.begin();surfit!=surflist.end();surfit++){
						if((*surfit).materialid==m){
							bbPaintSurface((*surfit).id,brush);
						}
					}

					bbFreeBrush(brush);

				}
			myfile->close();
		}

	delete myfile;
	return mesh;
	}



	void Run(){

		BBObject mesh=this->LoadTMF("C:\\as.tmf");
		bbPositionEntity(mesh,0,0,70);

		

		while(bbKeyHit(1)==0)
		{
			bbTurnEntity(mesh,1,1,1);
			bbRenderWorld();
			bbFlip();

		}

	}


	void End(){
		bbEndBlitz3D();
	};


};

Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Beitrag von milan1612 »

X0r hat geschrieben:

Code: Alles auswählen

string GetPathPart(const char* filen){
	int b=0;
	stringstream ftemp;
	string path,file;
	ftemp << filen;
	file=ftemp.str();
	
	for(unsigned int n=0;n<file.length();n++){
		if(file.substr(file.length()-n,1)=="/" || file.substr(file.length()-n,1)=="\"){
			b=n;
			break;
		}
	}
	path=file.substr(0,file.length()-b+1);
	return path;
}
Du brauchst hier keinen stringstream, string hat einen Constructor für const char*.
Nimm einfach string file(filen);

EDIT: Ach und warum allokierst du den ifstream dynamisch mit new?
Das ist erstens viel langsamer als der Stack und zweitens vollkommen sinnlos
innerhalb einer Funktion. Du verwendest ihn doch nur darin...
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Benutzeravatar
X0r
Beiträge: 2770
Registriert: 15.03.2007 21:47
Kontaktdaten:

Beitrag von X0r »

>Du brauchst hier keinen stringstream, string hat einen Constructor für const char*.
Nimm einfach string file(filen);

Stimmt ja :roll: ...dieses ganze stringstreamen und casten bringt einen manchmal durcheinander.

EDIT: Ach und warum allokierst du den ifstream dynamisch mit new?
Das ist erstens viel langsamer als der Stack und zweitens vollkommen sinnlos
innerhalb einer Funktion. Du verwendest ihn doch nur darin...
Stimmt ja, statisch wird er ja am Ende wieder freigegeben, nich?
Ich glaub ich hatte das erst als Objekt der app-klasse deklariert und später wieder abgeändert. Wäre ja dumm, dass dann nicht dynamisch zu allokieren.
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Beitrag von milan1612 »

X0r hat geschrieben:Stimmt ja, statisch wird er ja am Ende wieder freigegeben, nich?
Jupp, und close() brauchst du dann auch nicht aufrufen, denn ifstream folgt dem
RAII Prinzip, das heißt alle Resourcen werden mit dem Destruktoraufruf (der automatisch
passiert) freigegeben.
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Antworten