使用非ascii文件名调用_findfirst

时间:2016-06-10 09:35:07

标签: c localization

我有一个多字节Windows项目,我尝试访问一个文件,该文件可以具有现代Windows允许的任何符号的名称。但是,如果文件名包含非ASCII字符(日语,瑞典语,俄语等),我会失败。

例如:

const char * filename_ = "C:\\testÖ.txt"
struct _finddata_t fd;
long fh = _findfirst(filename_, &fd);

此时_findfirst()失败。

这里支持所有可能的文件名的最佳解决方案是什么?我读到_findfirst()取决于程序启动时设置的系统区域设置。好吧,我可以更改某个特定的那个但是在这种情况下如何确定文件名所需的语言环境?

项目必须保持多字节。

之前有没有人解决过这样的问题?

此外,我尝试使用宽字符转换,但也没有运气。代码示例如下:

debug_prnt("DEBUG: Checking existance of a file: %s\n", filename_);
struct _wfinddata_t ff;
size_t requiredSize = mbstowcs(NULL, filename_, 0);
wchar_t * filename = (wchar_t *)malloc((requiredSize + 1) * sizeof(wchar_t));
if (!filename)
{
    debug_prnt("ERROR: Memory allocation failed\n");
    return FALSE;
}
size_t size = mbstowcs(filename, filename_, requiredSize + 1);
if (size == (size_t)(-1))
{
    debug_prnt("ERROR: Couldn't convert string--invalid multibyte character.\n");
    return FALSE;
}

long fh = _wfindfirst(filename, &ff);
if (fh > 0)
    debug_prnt("DEBUG: File exists\n");
else
    debug_prnt("DEBUG: File does not exist %ls\n", filename);
free(filename);

1 个答案:

答案 0 :(得分:1)

这是一个简短但完整的Windows控制台应用程序,它使用您想要使用的功能。

这个程序的作用是在当前工作文件夹中创建一个要查找的文件,然后列出当前工作文件夹中扩展名为.txt的文件。

对于搜索条件,我使用的是硬编码的宽字符串。在您的情况下,您可能需要将字符串作为多字节字符串接受,将其转换为宽字符,然后将其与_wfindfirst()一起使用。

然而,在我的设置中,printf()似乎存在文本转换问题,因此打印到控制台的非ASCII文本中有一个奇怪的字符。但是调试器显示它很好。

// multibyte_file_search.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <locale.h>
#include <io.h>

int _tmain(int argc, _TCHAR* argv[])
{
    const char * filename_ = "testÖ.txt";
    FILE *fp = fopen (filename_, "w");
    fclose(fp);

    // test out mbstowcs()
    wchar_t *wcsFileName_ = new wchar_t[512];
    int requiredSize = mbstowcs(NULL,filename_,0);
    size_t xsize = mbstowcs(wcsFileName_,filename_,512);
    printf ("mbstowcs() return %d\n", xsize);

    // do an actual directory search on the current working directory.
    printf ("\n\n Directory search begins.\n");
    struct _wfinddata_t ff = {0};
    char *csFileName_ = new char[512];
    strcpy (csFileName_, "*.txt");
    xsize = mbstowcs(wcsFileName_,csFileName_,512);  // convert search to wide character.
    intptr_t  fh = _wfindfirst(wcsFileName_, &ff);

    if (fh != -1) {
        do {
            wcstombs (csFileName_, ff.name, 512);
            printf (" ff.name %S and converted name %s \n", ff.name, csFileName_);
            wprintf (L"     ff.name %s and converted name %S \n", ff.name, csFileName_);
        } while (_wfindnext (fh, &ff) == 0);
        _findclose (fh);
    } else {
        printf ("No files in directory.\n");
    }

    return 0;
}