【问题标题】:C++ _findfirst and TCHARC++ _findfirst 和 TCHAR
【发布时间】:2016-08-23 13:53:26
【问题描述】:

我得到了以下代码:

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);
}

它的作用是打印给定目录 (C:) 包含的所有内容的名称。现在我必须打印出子目录中所有内容的名称(如果有的话)。到目前为止,我已经得到了这个:

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);

}

现在我不要求提供整个解决方案(我希望能够自己完成),但只有一件事我无法理解,那就是 TCHAR* argv。我知道 argv[1] 包含我在“命令参数”下的项目属性中放置的内容,现在它包含我想要在 (C:/users/name/New folder/*) 中测试我的应用程序的目录,其中包含一些带有子文件夹的文件夹和一些随机文件。 argv[1] 当前给出以下错误:

错误:“_TCHAR*”类型的参数与“const char *”类型的参数不兼容

现在我搜索了 TCHAR,我知道它是 wchar_t* 或 char*,具体取决于使用 Unicode 字符集或多字节字符集(我目前使用的是 Unicode)。我也明白转换是一个巨大的痛苦。所以我要问的是:我怎样才能最好地使用 _TCHAR 和 _findfirst 参数解决这个问题?

我打算将 dirEntry.name 连接到 argv[1] 并在末尾连接一个“*”,并在另一个 _findfirst 中使用它。由于我仍在学习 C++,因此我的代码中的任何 cmets 都会受到赞赏。

【问题讨论】:

  • _TCHAR 是一个应该在“windows.h”中定义的宏。您是否包含此标头?
  • 我正在使用带有预编译头的 Visual Studio 2015,所以我猜是这样

标签: c++ argv tchar findfirst


【解决方案1】:

参见此处:_findfirst 用于多字节字符串,而_wfindfirst 用于宽字符。如果您在代码中使用 TCHAR,则使用 _tfindfirst(宏),它将在非 UNICODE 上解析为 _findfirst,在 UNICODE 构建上解析为 _wfindfirst。

还可以使用 _tfinddata_t 代替 _finddata_t,这也将根据 UNICODE 配置解析正确的结构。

另一件事是你也应该使用正确的文字,_T("C:/*") 在 UNICODE 构建上将是 L"C:/*",否则 "C:/*"。如果您知道您正在使用定义的 UNICODE 进行构建,请使用 std::vector&lt;std::wstring&gt;

顺便说一句。默认情况下,Visual Studio 将使用 UNICODE 创建项目,您只能使用像 _wfindfirst 这样的广泛版本的函数,因为没有充分的理由构建非 UNICODE 项目。

TCHAR,我知道它是 wchar_t* 还是 char*,具体取决于使用 UTF-8 字符集还是多字节字符集(我目前使用的是 UTF-8)。

这是错误的,在 UNICODE windows apis 中使用 UTF-16。 sizeof(wchar_t)==2

【讨论】:

  • 所以要么改成 _tfindfirst/_tfinddata_t 要么完全去掉 TCHAR?
  • Visual Studio 将使用 TCHAR.h 生成代码,因此为了保持一致,最好使用 TCHAR.h。您可以在这里找到这些映射:msdn.microsoft.com/en-us/library/szdfzttz.aspx。但是在您的代码中,您可以使用广泛版本的函数 - 代码将编译。我个人使用 TCHAR.h。
  • @Arrrow 实际上,一旦您更改项目设置,您的代码应该“神奇地”开始工作:General->Character Set to 'Use Multi-Byte Character Set'。但我建议您继续使用 UNICODE 并修复您的代码。
【解决方案2】:

使用这个简单的typedef

typedef std::basic_string&lt;TCHAR&gt; TCharString;

然后在您使用std::string 的任何地方使用TCharString,例如这里:

vector<TCharString> dirArray;

有关std::basic_string 的信息,请参见此处。

【讨论】:

  • 这会和普通的 std::string 一样吗?
  • @Arrrow -- 这就是这个模板的美妙之处 -- 是的,它应该和std::string 完全一样。为什么不试试看呢?
猜你喜欢
  • 2015-02-09
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多