Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   C++ IntToStr zu WCHAR (https://www.delphipraxis.net/193475-inttostr-zu-wchar.html)

EWeiss 4. Aug 2017 08:45


IntToStr zu WCHAR
 
Kann mir jemand helfen weis nicht wie ich das in C++ rüber bringen soll.

Delphi-Quellcode:
intToStr(Second div 60) + 'Min ' + intToStr(Second mod 60) + 'Sec';


Der Wert soll an WCHAR (Unicode) übergeben werden.
Danach will ich den Text mit SetWindowText an meinen Label schicken.

Das ist soweit klar
Code:
(Second / 60) + L"Min " + (Second %= 60) + L"Sec";

gruss

Fritzew 4. Aug 2017 09:56

AW: IntToStr zu WCHAR
 
Hallo Emil

tue Dir selbst einen gefallen und beschäftige Dich etwas mit
std::wstring und Co

Wenn es um Stringhandling geht ist C++ etwas ganz anderes als Delphi.

Es lohnt sich die Std Lib zumindest etwas zu kennen.

Gruss

EWeiss 4. Aug 2017 20:16

AW: IntToStr zu WCHAR
 
sorry doppelt kann gelöscht werden.

gruss

EWeiss 4. Aug 2017 20:20

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Fritzew (Beitrag 1378054)
Hallo Emil

tue Dir selbst einen gefallen und beschäftige Dich etwas mit
std::wstring und Co

Wenn es um Stringhandling geht ist C++ etwas ganz anderes als Delphi.

Es lohnt sich die Std Lib zumindest etwas zu kennen.

Gruss

Da magst recht haben hilft mir aber nicht bei meinem aktuellen Problem.
Das ist ein Projekt in C++ das ich nur einmal erstelle dann wende ich mich wieder Delphi zu.
C++ ist komplett anders als Delphi :)

Warum muss ich jetzt das Komplette MSVC in 3 stunden erlernen wegen 1 Funktion (Frage) wenn mir dabei jemand helfen könnte.


gruss

Zacherl 4. Aug 2017 21:41

AW: IntToStr zu WCHAR
 
Sofern du keinen älteren Standard als C++11 unterstützen willst, kannst du dafür
Delphi-Quellcode:
std::string s = std::to_string(42);
verwenden. Die
Delphi-Quellcode:
std::string
Klasse kann auch appenden und sollte den + Operator überladen haben, sodass du die Stringkonkatenation genau wie in Delphi hierrüber handhaben kannst.

EWeiss 4. Aug 2017 21:44

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Zacherl (Beitrag 1378111)
Sofern du keinen älteren Standard als C++11 unterstützen willst, kannst du dafür
Delphi-Quellcode:
std::string s = std::to_string(42);
verwenden. Die
Delphi-Quellcode:
std::string
Klasse kann auch appenden und sollte den + Operator überladen haben, sodass du die Stringkonkatenation genau wie in Delphi hierrüber handhaben kannst.

Ich komme mit der Formatierung nicht zurecht ;)
Der Ausgangsstring ist WCHAR nicht string. :)

gibt es das?
Code:
std::to_string(42).wchar_t;
gruss

Zacherl 4. Aug 2017 21:49

AW: IntToStr zu WCHAR
 
Ja analog zu
Delphi-Quellcode:
std::string
gibt es auch
Delphi-Quellcode:
std::wstring
:P

Edit:
Und
Delphi-Quellcode:
std::to_wstring

EWeiss 4. Aug 2017 21:55

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Zacherl (Beitrag 1378113)
Ja analog zu
Delphi-Quellcode:
std::string
gibt es auch
Delphi-Quellcode:
std::wstring
:P

Edit:
Und
Delphi-Quellcode:
std::to_wstring

Code:
WCHAR StreamLenght = std::to_wstring(Second / 60) + L"Min " + std::to_wstring(Second %= 60) + L"Sec";
Zitat:

Fehler (aktiv) E0413 Es ist keine passende Konvertierungsfunktion von ""std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>"" in ""WCHAR"" vorhanden.
Zitat:

Fehler C2440 "Initialisierung": "std::basic_string<wchar_t,std::char_traits<wchar_ t>,std::allocator<wchar_t>>" kann nicht in "WCHAR" konvertiert werden
gruss

EWeiss 4. Aug 2017 23:13

AW: IntToStr zu WCHAR
 
So macht man aus einer Zeile 11

Delphi-Quellcode:
        INT64 Second = (aMediaProperty.PlaybackLength / 10000) / 1000;
       
        WCHAR Minutes[MAX_PATH];
        WCHAR Seconds[MAX_PATH];
        WCHAR StreamLenght[MAX_PATH];
        // Minuten
        std::wstring Min_tmp = std::to_wstring(Second / 60);
        WCHAR * Min = &Min_tmp[0];
        Str_Combine(Minutes, Min, L" Min ");
        // Sekunden
        std::wstring Sec_tmp = std::to_wstring(Second %= 60);
        WCHAR * Sec = &Sec_tmp[0];
        Str_Combine(Seconds, Sec, L" Sec");
        // Kombinieren
        Str_Combine(StreamLenght, Minutes, Seconds);
        // Ausgabe
        SetWindowText(hLblStreamLenght, StreamLenght);
Was für ein Schmarrn. Eine andere Lösung fällt mir nicht ein.
Wenn ich das jetzt hiermit auch noch machen muss dann habe ich 50 Zeilen anstelle von 3

Delphi-Quellcode:
        //lbl_VideoInfo.Caption : = FormatFloat('#,##0', aMediaProperty.Video_Width) + ' x ' +
        //    FormatFloat('#,##0', aMediaProperty.Video_Height) + ', ' +
        //    FormatFloat('##0.00', aMediaProperty.Video_FPS) + ' FPS';
        //SetWindowText(hlblVideoInfo, VideoInfo);
        //lbl_AudioProperty.Caption : = intToStr(aMediaProperty.Audio_Channels) + ' Channel, ' +
        //    FormatFloat('#,##0', aMediaProperty.Audio_Samplerate) + ' SPS, ' +
        //    intToStr(aMediaProperty.Audio_BitsPerSample) + ' BPS';
        //SetWindowText(hlblAudioProperty, AudioProperty);
gruss

Zacherl 5. Aug 2017 00:57

AW: IntToStr zu WCHAR
 
Dein Fehler kommt daher, dass du deine Variable als
Delphi-Quellcode:
WCHAR
(einzelnes Zeichen = WideChar) deklarierst und nicht als
Delphi-Quellcode:
WCHAR*
(PWideChar).

EWeiss 5. Aug 2017 01:02

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Zacherl (Beitrag 1378117)
Dein Fehler kommt daher, dass du deine Variable als
Delphi-Quellcode:
WCHAR
(einzelnes Zeichen = WideChar) deklarierst und nicht als
Delphi-Quellcode:
WCHAR*
(PWideChar).

Sorry ist das gleiche Problem ;)
Code:
WCHAR * StreamLenght = std::to_wstring(Second / 60) + L"Min " + std::to_wstring(Second %= 60) + L"Sec";
Zitat:

Fehler (aktiv) E0413 Es ist keine passende Konvertierungsfunktion von ""std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>"" in ""WCHAR *"" vorhanden.
Zitat:

Fehler C2440 "Initialisierung": "std::basic_string<wchar_t,std::char_traits<wchar_ t>,std::allocator<wchar_t>>" kann nicht in "WCHAR *" konvertiert werden
Danke.

gruss

Zacherl 5. Aug 2017 01:11

AW: IntToStr zu WCHAR
 
Probier mal:
Delphi-Quellcode:
std::wstring streamLength = std::to_wstring(Second / 60) + L"Min " + std::to_wstring(Second %= 60) + L"Sec";
const WCHAR* ptr = streamLength.c_str();
Der Assignment Operator ist scheinbar nicht überladen.

EWeiss 5. Aug 2017 01:20

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Zacherl (Beitrag 1378119)
Probier mal:
Delphi-Quellcode:
std::wstring streamLength = std::to_wstring(Second / 60) + L"Min " + std::to_wstring(Second %= 60) + L"Sec";
const WCHAR* ptr = streamLength.c_str();
Der Assignment Operator ist scheinbar nicht überladen.

Ja genau das habe ich vorher auch versucht.
Das Problem dabei ist das dann die Berechnung von (Second / 60) fehlschlägt.
Seltsamer weise stimmen aber die Sekunden (Second %= 60). (Second mod 60).

Zudem kommt noch das ich einen "const WCHAR*" nicht an SetWindowText übergeben kann.
So! stimmen die
Code:
        std::wstring Min_tmp = std::to_wstring(Second / 60);
        WCHAR * Min = &Min_tmp[0];
gruss

Zacherl 5. Aug 2017 01:43

AW: IntToStr zu WCHAR
 
Also
Delphi-Quellcode:
%=
ist zumindest auch falsch, es muss nur
Delphi-Quellcode:
%
sein.
Delphi-Quellcode:
var += value
und Konsorten sind Kurzformen von
Delphi-Quellcode:
var = var + value
.

So funktioniert es bei mir ohne Probleme:
Delphi-Quellcode:
uint32_t seconds = 350;

std::wstring title = std::to_wstring(seconds / 60) + L"Min " + std::to_wstring(seconds % 60) + L"Sec";

AllocConsole;
SetWindowTextW(GetConsoleWindow(), title .c_str());

EWeiss 5. Aug 2017 01:53

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Zacherl (Beitrag 1378121)
Also
Delphi-Quellcode:
%=
ist zumindest auch falsch, es muss nur
Delphi-Quellcode:
%
sein.
Delphi-Quellcode:
var += value
und Konsorten sind Kurzformen von
Delphi-Quellcode:
var = var + value
.

So funktioniert es bei mir ohne Probleme:
Delphi-Quellcode:
uint32_t seconds = 350;

std::wstring title = std::to_wstring(seconds / 60) + L"Min " + std::to_wstring(seconds % 60) + L"Sec";

AllocConsole;
SetWindowTextW(GetConsoleWindow(), title .c_str());

Das ist nett von dir Danke..
So funktioniert es 100%. Kann also die 100 Zeilen wieder löschen.

Wenn du möchtest kannst mir dabei auch noch helfen. ? :duck:
Delphi-Quellcode:
         //lbl_VideoInfo.Caption : = FormatFloat('#,##0', aMediaProperty.Video_Width) + ' x ' +
         // FormatFloat('#,##0', aMediaProperty.Video_Height) + ', ' +
         // FormatFloat('##0.00', aMediaProperty.Video_FPS) + ' FPS';
         //SetWindowText(hlblVideoInfo, VideoInfo);
         //lbl_AudioProperty.Caption : = intToStr(aMediaProperty.Audio_Channels) + ' Channel, ' +
         // FormatFloat('#,##0', aMediaProperty.Audio_Samplerate) + ' SPS, ' +
         // intToStr(aMediaProperty.Audio_BitsPerSample) + ' BPS';
         //SetWindowText(hlblAudioProperty, AudioProperty);
Danach wären die String Probleme beseitigt.

gruss

Zacherl 5. Aug 2017 02:10

AW: IntToStr zu WCHAR
 
Float Conversions mit bestimmter Präzision und Formatierung sind etwas umständlich bei C++. Es gibt mehrere Möglichkeiten:
https://stackoverflow.com/questions/...decimal-digits

Also entweder über
Delphi-Quellcode:
std::stringstream
und
Delphi-Quellcode:
set::setw()
und
Delphi-Quellcode:
set::setprecision()
. Oder über die C-Style Format Funktionen wie
Delphi-Quellcode:
std::snprintf
.

Da müsstest du schauen, was dir lieber ist.

EWeiss 5. Aug 2017 02:19

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Zacherl (Beitrag 1378124)
Float Conversions mit bestimmter Präzision und Formatierung sind etwas umständlich bei C++. Es gibt mehrere Möglichkeiten:
https://stackoverflow.com/questions/...decimal-digits

Also entweder über
Delphi-Quellcode:
std::stringstream
und
Delphi-Quellcode:
set::setw()
und
Delphi-Quellcode:
set::setprecision()
. Oder über die C-Style Format Funktionen wie
Delphi-Quellcode:
std::snprintf
.

Da müsstest du schauen, was dir lieber ist.

Ok ;)
Werde mich mal umsehen.

gruss

EWeiss 5. Aug 2017 07:44

AW: IntToStr zu WCHAR
 
So geht's aber auch wieder so viele Zeilen ;)
Inklusive kleinen Helfern.

Code:
#define long_proc_c typedef long (__cdecl *Proc)
Code:
HMODULE MSVCRT() {
    static HMODULE hModule;
    if (hModule == 0) { hModule = LoadLibrary(L"MSVCRT"); }
    return hModule;
}
Code:
long Add_Str(OUT WCHAR* dest, IN WCHAR* srce) {
    long nRet = -1; // Error
    HMODULE hModule = MSVCRT();
    if (hModule) {
        long_proc_c(WCHAR*, WCHAR*, size_t);
        Proc hProc = (Proc)GetProcAddress(hModule, "wcsncat");
        if (hProc) { nRet = hProc(dest, srce, _TRUNCATE); }
    }
    return nRet;
}
Code:
       
Add_Str(VideoInfo, STRL(aMediaProperty.Video_Width));
Add_Str(VideoInfo, L" x ");
Add_Str(VideoInfo, STRL(aMediaProperty.Video_Height));
Add_Str(VideoInfo, L", ");
Add_Str(VideoInfo, STRD(aMediaProperty.Video_FPS));
Add_Str(VideoInfo, L" FPS");
SetWindowText(hLblVideoInfo, VideoInfo);
gruss

Fritzew 5. Aug 2017 11:27

AW: IntToStr zu WCHAR
 
Zu Deiner Lösung sag ich jetzt nix.........

Code:
#include <stdio.h>

wchar_t Buffer[100];
int err = _snwprintf_s(Buffer, 100, 99, L"%.3f x %.3f y , %6.2f FPS", aMediaProperty.Video_Width, aMediaProperty.Video_Height, aMediaProperty.Video_FPS);
if (err <0){
 // Buffer to small fix it
}
else
SetWindowText(hLblVideoInfo, Buffer);

EWeiss 5. Aug 2017 12:43

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Fritzew (Beitrag 1378142)
Zu Deiner Lösung sag ich jetzt nix.........

Code:
#include <stdio.h>

wchar_t Buffer[100];
int err = _snwprintf_s(Buffer, 100, 99, L"%.3f x %.3f y , %6.3f FPS", aMediaProperty.Video_Width, aMediaProperty.Video_Height, aMediaProperty.Video_FPS);
if (err <0){
 // Buffer to small fix it
}
else
SetWindowText(hLblVideoInfo, Buffer);

Es wäre schön wenn du etwas gesagt hättest ;)
Gut dann ich.. selbst erarbeitet. (Stolz)

Warum soll ich die MSVC.. hehehhe (VCL) verwenden wenn es nicht nötig ist?
Warum künstlich den Code um 250 KB und hoch vergrößern wenn es auch statisch zu lösen ist.
Ok ist nicht schön aber NONVCL oops meine natürlich NONMSVC.

Aber Danke für deinen Lösungsansatz.
Würde gerne wissen wie sich deine Lösung zusammen setzt.
Also die Formatierung. :)

Auch in C++ kann man eine EXE von 3 MB und mehr erstellen es geht aber auch in 64 KB das ist kein Witz,

Zitat:

warning C4477: "_snwprintf_s": Die Formatzeichenfolge "%.3f" erfordert ein Argument vom Typ "double", das variadic-Argument "1" weist aber den Typ "int" auf.
warning C4477: "_snwprintf_s": Die Formatzeichenfolge "%.3f" erfordert ein Argument vom Typ "double", das variadic-Argument "2" weist aber den Typ "int" auf.
Code:
WCHAR* STRD(IN double N) {
    static WCHAR ws[128] = { 0 };
    swprintf(ws, strSize(ws), L"%f", N);
    return (WCHAR*)ws;
}
oder
Code:
WCHAR VideoInfo[MAX_PATH] = { 0 };
_snwprintf_s(VideoInfo, MAX_PATH, 259, L"%d x %d, %6.3f FPS", aMediaProperty.Video_Width, aMediaProperty.Video_Height, aMediaProperty.Video_FPS);
SetWindowText(hLblVideoInfo, VideoInfo);
ok glaube habe es verstanden.. Danke
Code:
WCHAR AudioProperty[MAX_PATH] = { 0 };
_snwprintf_s(AudioProperty, MAX_PATH, 259, L"%d Channel, %d SPS, %d BPS", aMediaProperty.Audio_Channels, aMediaProperty.Audio_Samplerate, aMediaProperty.Audio_BitsPerSample);
SetWindowText(hLblAudioProperty, AudioProperty);
gruss

Zacherl 5. Aug 2017 14:16

AW: IntToStr zu WCHAR
 
Zu deiner Lösung Emil:
Vom manuellen Importieren einer Runtime Funktion würde ich dringend abraten. Die C/C++ Kompiler haben aber allgemein auch nicht das "Delphi-Problem", dass das einfache Inkludieren einer Datei auf einmal die Größe des Kompilats exorbitant in die Höhe schießen lässt (in C/C++ gibt es keine inbuilt RTTI und unbenutzte Symbols packt der Linker eh in keinem Falle ins Kompilat) - da musst du dir also keinerlei Gedanken machen, wenn du Standard-Header einbindest.

Zur Lösung von Fritzew:
Hier sollte man evtl. noch drauf hinweisen, dass
Delphi-Quellcode:
_snwprintf_s
nicht im C-Standard vorhanden ist. Kompilieren klappt also nur mit MSVC. Sollte bei deinem aktuellen Projekt wohl aber kein Problem sein, da deine DLL ja eh Windows-spezifisch ist (wobei man durchaus auch mit CLang und einigen anderen Compilern für Windows Targets compilen könnte, wenn man denn will).

EWeiss 5. Aug 2017 14:33

AW: IntToStr zu WCHAR
 
Zitat:

Zitat von Zacherl (Beitrag 1378145)
Zu deiner Lösung Emil:
Vom manuellen Importieren einer Runtime Funktion würde ich dringend abraten. Die C/C++ Kompiler haben aber allgemein auch nicht das "Delphi-Problem", dass das einfache Inkludieren einer Datei auf einmal die Größe des Kompilats exorbitant in die Höhe schießen lässt (in C/C++ gibt es keine inbuilt RTTI und unbenutzte Symbols packt der Linker eh in keinem Falle ins Kompilat) - da musst du dir also keinerlei Gedanken machen, wenn du Standard-Header einbindest.

Zur Lösung von Fritzew:
Hier sollte man evtl. noch drauf hinweisen, dass
Delphi-Quellcode:
_snwprintf_s
nicht im C-Standard vorhanden ist. Kompilieren klappt also nur mit MSVC. Sollte bei deinem aktuellen Projekt wohl aber kein Problem sein, da deine DLL ja eh Windows-spezifisch ist (wobei man durchaus auch mit CLang und einigen anderen Compilern für Windows Targets compilen könnte, wenn man denn will).

Danke für die Infos..
Zu meiner Lösung ;)
Ich war halt Stolz das ich es selbst ohne fremde Hilfe geschafft habe das Problem zu lösen wenn auch nicht auf die feine art. :)

Diese von Fritzew gefällt mir natürlich besser und kompilieren lässt es sich auch. (Header dafür war vorher schon eingebunden)
So habe ich zumindest gelernt wie man einen String in C++ Formatiert das kommt ja immer wieder vor.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz