C++ 如何在Windows中比较可能的备选文件名?

C++ 如何在Windows中比较可能的备选文件名?,c++,windows,filenames,C++,Windows,Filenames,不幸的是,Windows中的目录/文件名不区分大小写 当我将文本(用户输入)与目录名(来自CFileFind)进行比较时,如何检查它们是否表示相同的目录? 例如C:\PIPPO\和C:\PIPPO\是同一个目录,而C:\Pipp\则不一样(最后一个有重音) 我正在尝试: if(CompareString(LOCALE_INVARIANT,NORM_IGNORECASE,q,-1,data_from_CfileFind->txt.GetBuffer(),-1)==CSTR_EQUAL) (

不幸的是,Windows中的目录/文件名不区分大小写

当我将文本(用户输入)与目录名(来自
CFileFind
)进行比较时,如何检查它们是否表示相同的目录? 例如
C:\PIPPO\
C:\PIPPO\
是同一个目录,而
C:\Pipp\
则不一样(最后一个有重音)

我正在尝试:

if(CompareString(LOCALE_INVARIANT,NORM_IGNORECASE,q,-1,data_from_CfileFind->txt.GetBuffer(),-1)==CSTR_EQUAL)
q
是用户输入的[部分])

这是一种“工作方式”,因为它将罗马、希腊和西里尔字母的大小写变体识别为同一目录,但它混淆了
“weiß”
“weiss”
(它们是我光盘上的两个不同目录),因此不可靠

[失败测试的灵感来自:我读过,但没有找到合适的解决方案-链接似乎不起作用)

(我也读过,但恐怕我没有完全理解“文化”)

有什么建议吗

也许我应该用不同的参数调用
CompareString()
,或者有更好更简单的方法吗

请注意,我不需要对名称进行排序:我只想检查它们对Windows是否意味着相同的目录(或文件)

我所说的“Windows”,是指2000年(或至少XP)及以后的版本

编辑(对不起,第一次问这个问题时问得不好)

1) 用户输入的路径不能保证引用实际存在的目录(在本例中,当然,它们不是同一个目录)

2) 我知道文件和目录可以用非常不同的名称引用,因为链接(硬或软),
subst
s,不同名称的网络访问或同一台计算机的IP等等……但我不要求检测所有这些情况。 我想检查的是,用户编写的名称是否是另一个现有名称的大小写变体(因此,例如,如果我尝试创建一个名称相同但大小写不同的文件,Windows会告诉我该文件已经存在)

第二次编辑

这就是工作(至少在我尝试过的情况下):

但是
CompareStringOrdinal()
在较旧的Windows版本中不可用。
是否有任何等效项?

首先调用每个路径,然后对结果进行不区分大小写的比较

GetFullPathName
将为每个文件提供一个完全限定的路径。
GetLongPathName
然后获取该路径中每个组件的真实名称,因此如果有人使用Windows 95/98样式的短名称作为文件/目录,这不会混淆问题。

这是最好的方法(据我所知)要检查两个文件系统路径是否引用同一项而不进行字符串比较,请执行以下操作之一:

  • 使用打开两个路径的
    HANDLE
    s,然后从
    HANDLE
    s获取唯一的文件系统ID,并比较它们是否相等。在FAT和NTFS上,使用
    dwVolumeSerialNumber
    nFileIndex(低|高)的组合
    from。在参考上,使用
    VolumeSerialNumber
    FileId
    from的组合。您可以使用来检测每个路径正在使用哪个文件系统

    该方法分别在和文件中描述:

    标识符(低位和高位部分)和卷序列号可唯一标识一台计算机上的文件。若要确定两个打开的句柄是否代表同一个文件,请将每个文件的标识符和卷序列号组合起来,并进行比较

    文件的128位文件标识符。文件标识符和卷序列号唯一地标识一台计算机上的文件。若要确定两个打开的句柄是否代表同一个文件,请将每个文件的标识符和卷序列号组合起来,并对其进行比较

  • 一种与文件系统无关的方法是获取Shell名称空间的根桌面的接口,然后使用桌面的方法(或使用独立函数)将两条路径解析为绝对PIDL,然后使用桌面的方法比较PIDL


  • 这就是它的工作方式:

    1) 在程序开始时,调用
    setlocale(LC\u CTYPE,”);


    2) 然后将字符串与
    if(!data\u from\u CfileFind->txt.CompareNoCase(q))
    (调用
    \u wcsicmp
    调用
    \u wcsicmp\u l
    )进行比较。

    这有帮助吗?“最后对结果进行不区分大小写的比较”正是我的问题。我如何执行它?我尝试了
    比较(LOCALE_不变量,NORM_IGNORECASE…
    但它混淆了
    weiß
    weiss
    这两个不同的目录。恐怕我在这个问题上误导了您(请参见“编辑”)。但是,
    CreateFile()
    在某些目录上不起作用(如
    C:\System Volume Information
    -但我无法创建例如
    C:\System Volume Information
    ,因为它将是同一个目录…)。我将尝试方法2。或更简单的方法。非常感谢您的回答。
    if(CompareStringOrdinal(q,-1,data_from_CfileFind->txt.GetBuffer(),-1,1)==CSTR_EQUAL)