Konvertierung CString nach LPCTSTR
-
Hallo,
ich habe folgende Member-Funktion, mit der ich eine Zeitdifferenz formatieren will. In der Funktion alloziiere ich Speicher fuer den String, nachdem ich ihn formatiert habe und gebe ihn ueber einen LPCTSTR zurueck. Leider schlaegt mir der cast an der markierten Zeile fehl. Wie kann ich das Problem loesen?
Vielen Dank fuer Hilfen.
LG
Mike
void CStatistics::FormatNewTime(COleDateTimeSpan& tTimeSpan, LPCTSTR sTimeSpan) { // convert timespan to CString CString s = tTimeSpan.Format("%H:%M:%S"); CString hour, minute, second; CStringTokenizer Tokens(s, _T(":"), FALSE); hour = Tokens.GetAt(0); if(hour.GetLength() == 1) hour = "0"+hour; minute = Tokens.GetAt(1); if(minute.GetLength() == 1) minute = "0"+minute; second = Tokens.GetAt(2); if(minute.GetLength() == 1) second = "0"+second; CString tmp = hour+":"+minute+":"+second; sTimeSpan = new CString(tmp); // klappt nicht !!!!! }
-
Da mußt du dir erstmal klarmachen, was "LPCTSTR" überhaupt ist - ein typedef für 'const TCHAR*'. Das bedeutet erstens, daß die Funktion eine lokale Kopie des Parameters bekommt und die Zuweisung keine Wirkung nach außen hat, und zweitens, daß du den Inhalt des übergebenen Strings nicht ändern darfst (siehe 'const'). Die einfachste Lösung dafür wäre es wohl, den Parameter zu ändern zu einem 'CString& sTimeSpan'.
-
Danke fuer die schnelle Antwort.
Ich hatte zuerst als Rueckgabe typ ein CString& gehabt, aber da ich das in der oberen Ebene in ein Struct speichere welches sich wiederrum in einen STL vector befindet, hat mir ein Arbeitskollege gesagt ich solle besser ein LPCTSTR benutzen da man sonst den Speicher im vector zerschiessen koennte, da man keine fixe groesse des Strings hat. Stimmt das so ? Von der Logik eher kann ich das schon nachvollziehen, aber mein Programm hat vorher ohne Probleme gefunzt.
-
void CStatistics::FormatNewTime(COleDateTimeSpan& tTimeSpan, CString& sTimeSpan) { // convert timespan to CString CString s = tTimeSpan.Format("%H:%M:%S"); CString hour, minute, second; CStringTokenizer Tokens(s, _T(":"), FALSE); hour = Tokens.GetAt(0); if(hour.GetLength() == 1) hour = "0"+hour; minute = Tokens.GetAt(1); if(minute.GetLength() == 1) minute = "0"+minute; second = Tokens.GetAt(2); if(minute.GetLength() == 1) second = "0"+second; sTimeSpan = hour + ":" + minute + ":" + second; }
... ohne auf die restlichen Fehler zu achten ... Wayn. ..
-
mike2003 schrieb:
Danke fuer die schnelle Antwort.
Ich hatte zuerst als Rueckgabe typ ein CString& gehabt, aber da ich das in der oberen Ebene in ein Struct speichere welches sich wiederrum in einen STL vector befindet, hat mir ein Arbeitskollege gesagt ich solle besser ein LPCTSTR benutzen da man sonst den Speicher im vector zerschiessen koennte, da man keine fixe groesse des Strings hat. Stimmt das so ? Von der Logik eher kann ich das schon nachvollziehen, aber mein Programm hat vorher ohne Probleme gefunzt.
Deswegen ist es trotzdem besser, eine String-Klasse zu verwenden anstelle von nackten char-Zeigern (ob du dort CString oder std::string verwendest, macht nicht viel Unterschied). Mit nackten char*'s kannst du dir wesentlich einfacher den Speicher zerschießen (besonders wenn du sie dir aus einem CString geholt hast - der gibt nämlich nur temporär gültige Zeiger heraus).
PS: Ich bin mir nicht ganz sicher, aber kann CTimeSpan::Format() nicht selber diese Darstellung mit Nullen auffüllen?
-
CStoll schrieb:
PS: Ich bin mir nicht ganz sicher, aber kann CTimeSpan::Format() nicht selber diese Darstellung mit Nullen auffüllen?
COleDateTimeSpan::Format füllt automatisch den Rest mit Nullen auf, ausser beim Tag.
Wenn man eine eigene Darstellung haben will, dann geht man am besten über CString::Format.
CString str; // Der String COleDateTimeSpan odts; // Das COleDateTimeSpan Objekt str.Format(_T("%02d:%02d:%02d"), odts.GetHours(), odts.GetMinutes(), odts.GetSeconds());
Die in CString::Format benutzten Formate, sind die gleichen wie in printf und wprintf. Hier findest du die Beschreibung:
http://msdn2.microsoft.com/en-us/library/56e442dc.aspxGrüssli
-
Eure Ideen sind alle gut, nur das eigentliche Problem welches ich habe also ein CString an ein LPCTSTR zurueckzugeben, dieses funzt nicht. Also ich habe mal folgendes auf die Schnelle hier gepostet als Beispiel was ich eigentlich machen will, vieleicht ist das etwas klarer ausgedrueckt:
// befindet sich global in datei a.h struct tTest { ... LPCTSTR psFormatedTime; }; class CTest { ... }
// befindet sich in a.cpp void CTest::FormatTime(COleDateTimeSpan& time, LPCTSTR ftime) { ... CString s = hour+":"+minute+":"+second; ftime = new CString(); // sowas in der Art } // Aufruf der Funktion FormatTime von void CTest::TestTime() { ... TestStruct* tTest = new tTest(); COleDateTimeSpan oleTime; ... FormatTime(oleTime, TestStruct->psFormatedTime); // In psFormatedTime soll die formatierte Zeit ... }
-
Darf ich mal fragen, wieso du unbedingt ein LPCTSTR haben willst? Wieso kannst du dazu nicht ein CString verwenden? CString ist wesentlich besser, flexibler und angenehmer um damit zu arbeiten.
Ein LPCTSTR ist eigentlich, wie schon von CStoll gesagt, ein 'const TCHAR*'. TCHAR* ist entweder ein char* bei ASCII oder ein wchar_t* bei UNICODE.
Du kannst daher über CString::GetBuffer() die richtig information in ein LPCTSTR schreiben. Allerdings ist das in deinem Aufbau eine völlige Idiotie, wenn man es so machen würde.
Zudem würde sowieso nix passieren, da dein LPCTSTR Objekt nur in deiner Funktion existiert. Und nicht zu vergessen, über das LPCTSTR Objekt, könntest du das auf dem Heap angelegten CString Objekt nicht mehr löschen.
Also eigentlich von A bis Z ist es völliger Unsinn, was du da machen willst und zeigt darauf hin, dass es einen Denk/Designfehler irgendwo an einer anderen Stelle hatDeshalb antworte am besten auf die ersten 2 Fragen und wir können dir womöglich deutlich besser helfen
Grüssli
-
Lange Rede kurzer sinn ich habe mich nochmal mit meinen Arbeitskollegen zusammengesetzt und ihm auch gesagt das es besser ueber ein CString geht als ueber irgendwelche Pointer mit denen man das Programm zum abstuerzen bringen kann. Zum Glueck hat er endlich eingewilligt und ich mache das jetzt wie auch schon vorher mit einem CString.
Vielen Dank fuer Eure hilfen
LG
Mike