Forum: PC-Programmierung zusammengesetze Zeichenkette / wchar_t* / c++


von Jan L. (jan_l)


Lesenswert?

Hallo,

wie meine Überschrift schon sagt, möchte ich Zeichenketten bzw. ein Int 
mit einem wchar_t * verküpfen.

Hintergrund ist der, ich habe eine Api (für eine Kamera) und in der ist 
vorgegeben, dass ich, wenn ich einen Frame speichern möchte den Pfrad 
bzw. den Datei Name in diesem Format angebe.

Da ich jetzt aber dauerhaft Frames speicher will, möchte ich gerne eine 
fortlaufende Zahl im Dateinamen haben.

In etwa wie hier:
1
"C:\\" + FrameNummer + "_Frame.bmp"
Nur, dass das so natürlich nicht funktioniert.

Nach dem ich es gestern den ganzen Tag versucht habe und kein Stück 
vorangekommen bin dachte ich mir ich frag einfach mal nach =)

ps.: Normalerweiße habe ich mit c++ nicht so viel am Hut. Allerdings 
hatte ich gehofft das ich auch mit meinen eher dürftigen Kenntnissen ein 
Kleines Testprogramm hinbekomme.

von Jojo S. (Gast)


Lesenswert?

Die FrameNo muss erst in einen String gewandelt werden. Am einfachsten 
geht das mit
int n = wsprintf(buffer, _T"C:\\\\%i_Frame.bmp", FrameNummer);
So aus dem Kopf raus, ohne Gewähr.

von Jan L. (jan_l)


Lesenswert?

Jojo S. schrieb:
> int n = wsprintf(buffer, _T"C:\\\\%i_Frame.bmp", FrameNummer);

also int n? dann hab ich ja aber wieder ein int...
und was für einen buffer meinst du? da er mir sagt, dass ich diesen 
nicht initialisiert hab... was ja auch stimmt.

von Markus M. (mark_m)


Lesenswert?

C++ stellt dafür die stringstream-Klassen zur Verfügung.

Mit ostringstream kannst Du einen String zusammensetzen und als String 
weiterverarbeiten.
1
#include <sstream>
2
3
std::ostringstream path;
4
5
int FrameNummer = 1;
6
7
path << "C:\\" << FrameNummer << "_Frame.bmp" << std::ends;
8
9
std::string finishedpath = path.str();

Das Ausgabeformat deiner Zahl kannst über path.width( ... ) und 
path.fill( ... ) bestimmen.

Näheres findest Du in der C++ Literatur.

Grüsse

von Jan L. (jan_l)


Lesenswert?

so, nach dem ich jetzt nochmal gesucht habe, hab ich mir mal was 
zusammen gebastelt was zumindest keine Compilerfehler gibt.

und das sieht folgendermaßen aus.
1
wchar_t *cnt = reinterpret_cast<wchar_t *>(m_nCntSteal);
2
wchar_t* endung = L"_Frame.bmp";
3
wchar_t* dateiName = L"C:\\Frames\\";
4
  
5
wcscat(dateiName, cnt);
6
wcscat(dateiName, endung);

jetzt bin ich mal gespannt was er macht.

von Jan L. (jan_l)


Lesenswert?

ok irgendwas funktioniert leider garnicht,
bei dem wcscat bekomm ich währen der laufzeit immer was von wegen, dass 
wcscat eine zugriffsverletzung beim lesen hat...

von Jan L. (jan_l)


Lesenswert?

Markus M. schrieb:
> #include <sstream>
>
> std::ostringstream path;
>
> int FrameNummer = 1;
>
> path << "C:\\" << FrameNummer << "_Frame.bmp" << std::ends;
>
> std::string finishedpath = path.str();

also das funktioniert soweit. allerdings habe ich ja am ende einen ganz 
normalen String, welchen ich wieder nicht in meine wchar_t* Variable 
bekomme...

von Arc N. (arc)


Lesenswert?

Jan L. schrieb:
> so, nach dem ich jetzt nochmal gesucht habe, hab ich mir mal was
> zusammen gebastelt was zumindest keine Compilerfehler gibt.
>
> und das sieht folgendermaßen aus.
>
> [code]
>
> wchar_t *cnt = reinterpret_cast<wchar_t *>(m_nCntSteal);

^^^^^^^^^^^^^^^^^
m_nCntSteal wird als Zeiger auf wchar_t reinterpretiert...
wsprintf oder mehr C++
std::wstringstream wstream;
wstream << 1234 << std::ends;
const wchar_t* wstr = wstream.str().c_str();

> wchar_t* endung = L"_Frame.bmp";
> wchar_t* dateiName = L"C:\\Frames\\";

von Steffen (Gast)


Lesenswert?

Viele Wege führen nach Rom. Zwei anbei:

1
#include <iostream>
2
#include <sstream>
3
4
std::wstring make1(size_t infix) 
5
{
6
  std::ostringstream oss ;
7
  oss << "C:\\" << infix << "_Frame.bmp" ;
8
  std::string const& s = oss.str() ;
9
  return std::wstring(s.begin(),s.end()) ;
10
}
11
12
std::wstring make2(size_t infix)
13
{
14
  std::wstringstream owss ;
15
  owss << "C:\\" << infix << "_Frame.bmp" ;
16
  return owss.str() ;
17
}
18
19
int main()
20
{
21
  wchar_t const* wc1 = make1(23).c_str() ;
22
  std::wcout << wc1 << std::endl ;
23
24
  wchar_t const* wc2 = make2(42).c_str() ;
25
  std::wcout << wc2 << std::endl ;
26
27
  return 0 ;
28
}
1
> g++ test.cc -o test
2
> ./test
3
C:\23_Frame.bmp
4
C:\42_Frame.bmp

Grüße, Steffen

von Steffen (Gast)


Lesenswert?

Grmpf. Sehe gerade die auto variablen. Besser:
1
  std::wstring ws1 = make1(23) ;
2
  wchar_t const* wc1 = ws1.c_str() ;
3
  std::wcout << wc1 << std::endl ;

ws1 muss im Scope bleiben so lange Du wc1 benutzen möchtest. (Same for 
wc2).

von Jan L. (jan_l)


Lesenswert?

so nach dem ich von allem ein bisschen genommen habe, hab ich auch ein 
Ergebnis was mir die Dateinamen so wie ich es möchte nummeriert.

sieht jetzt so aus:
1
std::ostringstream path;
2
        
3
path << "C:\\Frames\\" << frameCnt << "_Frame.bmp" << std::ends;
4
5
std::string fp = path.str();
6
        
7
wchar_t* pfad;// = new wchar_t[100];
8
std::copy(fp.begin(), fp.end(), pfad);

von Jojo S. (Gast)


Lesenswert?

Jan L. schrieb:
> wchar_t* pfad;// = new wchar_t[100];
> std::copy(fp.begin(), fp.end(), pfad);

das Böse an C/C++ ist das etwas vielleicht funtkioniert aber trotzdem 
nicht richtig ist.
Dein Pointer 'pfad' ist nicht initialisiert und zeigt irgendwo hin. Und 
jetzt wird nach irgendwo der String hinkopiert -> du schreibst irgendwas 
im Speicher kaputt.
Der Ansatz mit new war schon richtig, du musst erst Platz schaffen für 
das Ergebnis. Das war auch in einigen Beispielen vorher schon nötig.

von Jan L. (jan_l)


Lesenswert?

ja hab ich auch gemerkt... mittlerweile ist das auch wieder drin.

von Jojo S. (Gast)


Lesenswert?

mit 'einfach' C:
1
// TestString.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
2
//
3
4
#include "stdafx.h"
5
#include "windows.h"
6
7
8
int _tmain(int argc, _TCHAR* argv[])
9
{
10
  int FrameNummer = 42;
11
  wchar_t filename[MAX_PATH + 1];
12
13
  int filename_length = wsprintf(filename, L"C:\\\\%i_Frame.bmp", FrameNummer);
14
15
  wprintf(filename);
16
17
  return 0;
18
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es dürfte übrigens sinnvoll sein, die Framenummer im Dateinamen mit 
führenden Nullen auszugeben; der Windows-Explorer sortiert sie sonst 
ziemlich, äh, beknackt.

Also statt

  wsprintf(filename, L"C:\\\\%i_Frame.bmp", FrameNummer);

besser

  wsprintf(filename, L"C:\\\\%04i_Frame.bmp", FrameNummer);

(je nach zu erwartender Stellenanzahl auch mehr als 4 verwenden)

von Peter II (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> der Windows-Explorer sortiert sie sonst
> ziemlich, äh, beknackt.

nö, er macht es richtig. Nur andere Programm (z.b. Totalcmd) bekommen 
das nicht hin.

Ich würde es aber auch mit der vornull machen.

von Jan L. (jan_l)


Lesenswert?

also ich habs jetzt mal bis 15K laufen lassen (danach ist leider meine 
Partition am Ende) aber die hat er vollkommen richtig sortiert.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.