Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » char*/string <-> WCHAR/wstring

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
20.11.2011, 14:26 Uhr
banshee



Hallo,

ich habe mich jetzt wieder stundenlang durch die 1000 String- und Char-Datentypen gewühlt, um erfolglos nach einer Lösung für ein eigentlich einfaches Problem zu lösen.
Ich lese einen Verzeichnisnamen in der main als char** ein und möchte später alle Dateien in diesem Verzeichnis lesen (die entsprechende Funktion erwartet einen const string&. Das Problem ist, dass ich zwischendrin auf Funktionen der WinAPI zurückgreifen muss:


C++:
void fct1(std::string dirName)
{
    WIN32_FIND_DATA wfd;
    HANDLE hFind = FindFirstFile(dirName, &wfd); // wie?
    FindNextFile(hFind, &wfd);

    while(FindNextFile(hFind, &wfd))
    {
        if(wfd.dwFileAttributes & !FILE_ATTRIBUTE_DIRECTORY)
        {
            readImg(wfd.cFileName); // hier wieder zurück
        }
    }

    FindClose(hFind);
}


Rein kommt also char** oder string, FindFirstFile erwartet einen WCHAR* und cFileName ist auch wieder WCHAR* das dann wieder in char** oder string zurück muss. Und egal was ich jetzte mache, es endet damit, dass ich einen Datentyp mit einer brachialen copy-Funktion in den anderen presse. Geht das nicht irgendwie schöner?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
20.11.2011, 15:58 Uhr
0xdeadbeef
Gott
(Operator)


Stell in den Projekteinstellungen ein, dass nicht der Unicode-Zeichensatz verwendet werden soll (Projekteigenschaften -> Konfigurationseigenschaften -> Allgemein -> Zeichensatz o.ä.), dann werden alle generischen WinAPI-Bezeichner auf die A-Funktionen gemappt.

Wahlweise kannst du auch direkt die Funktion FindFirstFileA benutzen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
20.11.2011, 18:30 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


oder überall wchar (bzw der heißt glaub wchar_t oder so?) und wstring benutzen ;-)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.11.2011, 12:28 Uhr
banshee



Stimmt auf die Idee von deadbeef hätte ich auch kommen können
Wie eine unicode-konforme Lösung aussehen würde, frage ich jetzt mal nicht
Ich kann leider nicht überall wchar/wstring nutzen, weil ich einmal ne Funktion aus opencv aufrufe, die zwangsläufig einen const string erwartet, d.h. mindestens 1x muss ich konvertieren.

Ich habe aber wie immer ein weiteres Problem, das ich bisher nur extrem unschön lösen kann:


C++:
// hier kommt ein Verzeichnisname rein in dem ich alle Dateien lesen will
void foo(char* dirName)
{
    WIN32_FIND_DATA wfd;
        // hier brauche ich dann dirName + "\\*" als regulären Ausdruck zur Suche
        // Problem ist aber dass strcat den ursprünglichen String manipuliert
    HANDLE hFind = FindFirstFile(strcat(dirName,"\\*"), &wfd);
    FindNextFile(hFind, &wfd);

    while(FindNextFile(hFind, &wfd))
    {
        if(wfd.dwFileAttributes & !FILE_ATTRIBUTE_DIRECTORY)
        {
                        // Hier brauche ich jetzt dirName (ohne die regex von oben) + wfd.cFileName
            readImg(wfd.cFileName);
        }
    }


    FindClose(hFind);
}


Ich könnte also einfach dirName in einem neuen char* kopieren, damit das Argument nicht manipuliert wird aber jedesmal wenn ich in der if-Anweisung eine Datei lese, mache ich dann ja wieder strcat(dirName_copy, wfd.cFileName) und ich habe das gleiche Problem wieder, ich müsste also nach jedem Durchlauf wieder eine neue Kopie von dirName anlegen. Ich suche da nach dem Java-Weg, einfach dirName + "abc" machen zu können und jedesmal ne Kopie anzulegen erscheint mir ziemlich hacky zu sein.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
21.11.2011, 17:53 Uhr
0xdeadbeef
Gott
(Operator)


Ich habe meine Zweifel daran, dass in einer Schleife, in der eine Funktion readImg vorkommt, die Stringbehandlung von Dateinamen groß ins Gewicht fällt. Im Übrigen legt Java auch jedes mal eine Kopie des Strings an, wenn du foo + bar schreibst.

Die einfachste Methode ist demnach

C++:
void foo(std::string dirName)
{
  dirName += "\\";

  WIN32_FIND_DATA wfd;

  HANDLE hFind = FindFirstFile((dirName + "*").c_str(), &wfd);
  if(INVALID_HANDLE_VALUE == hFind) {
    return;
  }

  do {
    // Ich vermute, dass es das ist, was du hier eigentlich willst:
    if(!(wfd.dwFileAttributed & FILE_ATTRIBUTE_DIRECTORY)) {
      readImg((dirName + wfd.cFileName).c_str());
    }
  } while(FindNextFile(hFind, &wfd) != INVALID_HANDLE_VALUE);

  FindClose(hFind);
}


Wenn Laufzeit hier tatsächlich kritisch ist, kann man natürlich dirName in einen Buffer schieben und in C-Manier den jeweils gewollten Teil hinten dranschreiben - die eigentliche Arbeit liegt dann darin, Buffer-Overflows zu verhindern. Aber wie gesagt, ich glaube da eigentlich nicht dran.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 21.11.2011 um 17:53 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
23.11.2011, 21:20 Uhr
banshee



ja, mir ging es weniger um die Laufzeit als viel mehr um die Lesbarkeit, denn da mit Buffern rumzuoperieren ist doch schon ziemlich low-level.
Im Moment funktioniert jedenfalls alles wunderbar, dafür schonmal vielen Dank und den Fehler in der if-Anweisung hatte ich vorher auch schon gefunden. Hab aber wohl ne alte Version kopiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: