2016-04-28 18 views
1

Ich habe den folgenden Code angegeben:C++ _findfirst und TCHAR

int _tmain(int argc, _TCHAR* argv[]) { 
    _finddata_t dirEntry; 
    intptr_t dirHandle; 
    dirHandle = _findfirst("C:/*", &dirEntry); 
    int res = (int)dirHandle; 
    while(res != -1) { 
     cout << dirEntry.name << endl; 
     res = _findnext(dirHandle, &dirEntry); 
    } 
    _findclose(dirHandle); 
    cin.get(); 
    return (0); 
} 

was dies tut druckt den Namen all dessen, was das angegebene Verzeichnis (C :) enthält. Jetzt muss ich den Namen von allem in den Unterverzeichnissen (wenn es welche gibt) ausgeben. Ich habe dies so weit gekommen:

int _tmain(int argc, _TCHAR* argv[]) { 
    _finddata_t dirEntry; 
    intptr_t dirHandle; 
    dirHandle = _findfirst(argv[1], &dirEntry); 
    vector<string> dirArray; 
    int res = (int)dirHandle; 
    unsigned int attribT; 
    while (res != -1) { 
     cout << dirEntry.name << endl; 
     res = _findnext(dirHandle, &dirEntry); 
     attribT = (dirEntry.attrib >> 4) & 1; //put the fifth bit into a temporary variable 
//the fifth bit of attrib says if the current object that the _finddata instance contains is a folder. 
     if (attribT) { //if it is indeed a folder, continue (has been tested and confirmed already) 
      dirArray.push_back(dirEntry.name); 
      cout << "Pass" << endl; 
      //res = _findfirst(dirEntry.name, &dirEntry); //needs to get a variable which is the dirEntry.name combined with the directory specified in argv[1]. 
    } 
} 
_findclose(dirHandle); 
std::cin.get(); 
return (0); 

}

Jetzt bin ich nicht für die ganze Lösung zu fragen (ich will, es zu tun in der Lage sein auf meinem eigenen), aber es gibt nur diese eine Sache Ich kann mir nicht vorstellen, was TCHAR * argv ist. Ich weiß, dass argv [1] enthält, was ich in meinen Projekteigenschaften unter "Befehlsargumente" eingegeben habe, und jetzt enthält dieses Verzeichnis das Verzeichnis, in dem ich meine Anwendung testen möchte (C:/users/name/New folder/*) einige Ordner mit Unterordnern und einigen zufälligen Dateien. Der argv [1] gibt zur Zeit folgende Fehlermeldung:

Error: argument of type "_TCHAR*" is incompatible with parameter of type "const char *"

Jetzt habe ich für die TCHAR gegoogelt und ich verstehe, es ist entweder ein wchar_t * oder char * abhängig von der Verwendung von Unicode-Zeichensatz oder Multi-Byte Zeichensatz (Ich verwende derzeit Unicode). Ich verstehe auch, dass das Umwandeln ein massiver Schmerz ist. Ich frage also: Wie kann ich das am besten mit dem Parameter _TCHAR und _findfirst umgehen?

Ich plane, den dirEntry.name zu dem argv [1] zu concaten sowie ein "*" am Ende zu verketten und dies in einem anderen _findfirst zu verwenden. Alle Kommentare zu meinem Code werden ebenfalls geschätzt, da ich immer noch C++ lerne.

+0

'_TCHAR' ist ein Makro, das in" windows.h "definiert sein sollte. Fügen Sie diesen Header ein? –

+0

Ich benutze Visual Studio 2015 mit einem vorkompilierten Header, also denke ich so – Arrrow

Antwort

1

Mit dieser einfachen typedef:

typedef std::basic_string<TCHAR> TCharString;

Dann TCharString verwenden, wo immer Sie std::string verwendet haben, wie hier:

vector<TCharString> dirArray; 

hier finden Sie Informationen zu std::basic_string.

+0

Wird dies die gleiche wie eine normale Std :: String? – Arrrow

+0

@Arrrow - Das ist die Schönheit dieser Vorlage - ja, es sollte genau wie 'std :: string' funktionieren. Warum nicht versuchen und sehen? – PaulMcKenzie

2

Siehe hier: _findfirst ist für Multibyte-Strings, während _wfindfirst für breite Zeichen ist. Wenn Sie TCHAR in Ihrem Code verwenden, dann verwenden Sie _tfindfirst (Makro), die zu _findfirst auf nicht UNICODE und _wfindfirst auf UNICODE-Builds auflösen wird.

Auch anstelle von _finddata_t verwenden Sie _tfinddata_t, das auch auflösen wird, um die Struktur abhängig von UNICODE config zu korrigieren.

Eine andere Sache ist, dass Sie auch korrekte Literal verwenden sollten, _T("C:/*") wird L"C:/*" auf UNICODE Build und "C:/*" anderenfalls sein. Wenn Sie wissen, dass Sie mit UNICODE definiert sind, verwenden Sie std::vector<std::wstring>.

btw. Visual Studio erstellt standardmäßig ein Projekt mit UNICODE, Sie können nur breite Versionen von Funktionen wie _wfindfirst verwenden, da es keinen guten Grund gibt, nicht UNICODE-Projekte zu erstellen.

TCHAR and I understand it is either a wchar_t* or a char* depending on using UTF-8 character set or multi-byte character set (I'm currently using UTF-8).

Dies ist falsch, in UNICODE-Fenstern verwendet Apis UTF-16. sizeof(wchar_t)==2.

+0

Also entweder zu _tfindfirst/_tfinddata_t wechseln oder den TCHAR komplett loswerden? – Arrrow

+0

Visual Studio generiert Code mit TCHAR.h, um konsistent zu bleiben, ist es besser, TCHAR.h zu verwenden. Diese Zuordnung finden Sie hier: https://msdn.microsoft.com/en-us/library/szdftztz.aspx. Aber in Ihrem Code können Sie breite Versionen von Funktionen verwenden - Code wird kompiliert. Ich persönlich benutze TCHAR.h. – marcinj

+0

@Arrrow Eigentlich sollte Ihr Code "magisch" anfangen zu arbeiten, sobald Sie in den Projekteinstellungen ändern: Allgemein-> Zeichensatz auf "Verwenden Multi-Byte-Zeichensatz". Aber ich schlage vor, du bleibst bei UNICODE und reparierst deinen Code. – marcinj