【问题标题】:Weird characters in a std::vector<TCHAR*>std::vector<TCHAR*> 中的奇怪字符
【发布时间】:2015-05-12 00:38:05
【问题描述】:

尝试获取所有子目录,最终获取子目录中的所有文件,并且我将 std::vector 作为对实际获取所有目录的函数的引用传递。我可以在函数中计算出 cFileName,但是一旦它返回 main,向量就会有奇怪的字符。

目前我的字符集可以使用 Unicode。当我使用多字节时,它实际上会打印奇怪的字符,现在它什么也不打印了。向量中确实有一些东西(directories.size() 返回值 > 0)

真的想不出别的了。希望这是一个好问题,哈哈。谢谢

#include <iostream>
#include <vector>
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

// Declare function prototypes
DWORD listDirectories(std::vector<TCHAR*>&);

// Global variable that holds the current working path of the program
TCHAR buffer[MAX_PATH];

void main()
{
    // Declare variables, dwCount for return value from listDirectories, directories stores all sub directories, cDirectory stores current directory
    DWORD dwCount;
    //std::vector<TCHAR*> directories;
    std::vector<TCHAR*> directories;
    TCHAR cDirectory[MAX_PATH];

    // Get current directory
    GetCurrentDirectory(MAX_PATH, buffer);

    // Set cDirectory (current directory) to buffer (ATM is current directory) + add \\ to the end and make it the working directory
    _tcscpy_s(cDirectory, buffer);
    _tcscat_s(cDirectory, L"\\*");

    // dwCount is count of how many directories found, to be used later
    dwCount = listDirectories(directories);

    // Range for loop to print each value in the std::vector<TCHAR*> directories
    for (auto tStr : directories) {
        // Doing wcout here prints weird characters.
        std::wcout << tStr << std::endl;
    }

    std::cin.get();
}   // end void main()

DWORD listDirectories(std::vector<TCHAR*> &directories)
{
    // Declare variables, count used for number of directories, hFind for FindFirstFile, data used to store file data
    DWORD count = 0;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA data;
    TCHAR currentDir[MAX_PATH];

    // Copy the current working directory into currentDir, will be used for subDir
    _tcscpy_s(currentDir, buffer);

    // Append "\\*" to buffer to make it a working directory
    _tcscat_s(buffer, L"\\*");

    // Find first file in the current working directory, storying data in data as a reference
    hFind = FindFirstFile(buffer, &data);

    // If hFind is not an invalid handle
    if (hFind != INVALID_HANDLE_VALUE) {
        // Go through each file in the directory
        do
        {
            // If the file attributes is a directory
            if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                // Create a sub directory
                TCHAR subDir[MAX_PATH];

                // Fill subDir with current directory + "\\" + dir name
                _tcscpy_s(subDir, currentDir);
                _tcscat_s(subDir, L"\\");
                _tcscat_s(subDir, data.cFileName);

                // Fill subDir with current directory + "\\" + dir name
                //sprintf_s(subDir, "%s%s%s", currentDir, "\\", data.cFileName);

                // Add directory to my directories (std::vector<TCHAR*>) if count > 1, because I don't want the "." and ".." directories
                if (count > 1){
                    directories.push_back(subDir);
                    // Doing wcout here prints the subDir just fine and works properly
                    std::wcout << subDir << std::endl;
                }

                // Add 1 to count, used as the return for how many directories found in the current directory
                count++;
            }
        } while (FindNextFile(hFind, &data) != 0);
    }

    // Return count of directories found. -2 to get rid of the "." and ".." directories
    return (count - 2);
}   // end DWORD listDirectories(std::vector<TCHAR*>&)

【问题讨论】:

  • 是时候停止使用 TCHAR 了,除非你仍然支持 Win98。

标签: c++ winapi tchar


【解决方案1】:

在您的 listDirectories() 函数中

TCHAR subDir[MAX_PATH];
...
directories.push_back(subDir);

subDir 是函数内do ... while 循环的本地数组,其生命周期随着循环的每次迭代而结束。

std::vector&lt;TCHAR*&gt; directories; 更改为std::vector&lt;std::basic_string&lt;TCHAR&gt;&gt; directories;,您的代码应该可以正常工作。现在,您将复制目录名称并将其添加到 vector


另一种选择是在处理 Windows API 时忘记所有 TCHAR 内容,而只使用所有内容的宽字符版本。

std::vector<std::wstring> directories;
wchar_t cDirectory[MAX_PATH];
...
hFind = FindFirstFileW(buffer, &data);

等等

【讨论】:

  • 使它成为 std::basic_string 完美无缺。我对 Windows 编码知之甚少,如果有的话。这只是我第一次尝试进入它。之所以选择 TCHAR,是因为我知道它是 char* 的 typdef,它支持多字节和 unicode。我只是要使用 wstring ,因为我知道它更简单,并且如果它可以与 Windows API 一起使用。谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-03-06
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2020-06-15
相关资源
最近更新 更多