【问题标题】:How to find the filename from a C++11 stat object's file serial number on Windows如何在 Windows 上从 C++11 stat 对象的文件序列号中查找文件名
【发布时间】:2018-03-02 12:04:43
【问题描述】:

因为在 Windows 中,使用 Visual Studio,__FILE__ 宏可以提供小写字符串,并且因为我需要知道正确大小写的文件名(用户认为),所以我正在尝试解决如何转换Windows 上到正确大小写的路径的全小写路径。

看起来使用 stat 获取有关文件的信息可能是一个很好的起点。

但是,给定一个 stat 对象,我如何获取文件名?

#include <sys/stat.h>
#include <string>

void test()
{
    std::string file_name = "C:\\WiNdoWs";
    struct stat statbuf;
    int stat_ok = stat(file_name.c_str(), &statbuf);
    auto file_serial_number = statbuf.st_ino;
    std::string full_file_name = ???;
}

或者还有其他 C++11 方法可以实现这一点吗?它只需要在 Windows 上工作,因此特定于 Windows 的解决方案(带代码)就可以了。

我们希望在不添加对 boost 文件系统或 Qt 的依赖或迁移到 C++17 的情况下做到这一点。

更新 1

对于上下文,代码位于仅标头测试框架中,该框架旨在根据包含测试的源文件的名称创建一些输出文件 - 因此名为 DemoTest.cpp 的测试文件将生成一个输出文件,其名称以DemoTest... 开头。

我们试图解决的问题是,对于某些 Visual Studio 编译器设置,输出文件名以 demotest... 开头。

所以这意味着stat 调用在编译时生成__FILE__ 的同一源文件上运行。

更新 2

在 Visual Studio 2017 中调试时,statbuf.st_ino 的值为零 - 大概是因为该值表示 Unix inode,而在 Windows 上没有这样的东西。

所以这整个方法行不通。

还有其他选择吗?

【问题讨论】:

  • 我会查看 GetLongPathNameGetFinalPathNameByHandle 之类的内容(来自 msdn 上的随机搜索)。
  • 还有GetFullPathName。我不太确定这和GetLongPathName 之间的区别。
  • 谢谢,我应该说我知道这些,但很难找到它们与 C++11 一起使用的现代示例。

标签: c++ c++11 filenames


【解决方案1】:

恐怕你会再次陷入困境,因为这取决于用户如何调用编译器......如果你说(例如在一个 Makefile 中)

A.o: A.c
    $(CC) A.c -o a.o

Windows 不会抱怨输出文件的大小写,因为这两种情况都指向同一个对象输出。但A.c 的情况不同。如果您尝试cc A.c 并且源文件以a.c 存储在文件系统中,那么您只有一种方法可以知道文件存储在文件系统中的实际名称......即在目录中搜索文件并停止当您找到与您正在搜索的文件匹配的文件时。因此,这是一种复杂(且昂贵)的方式,因此编译器通常不会遵循它,因此它将根据您传递给它的名称进行操作。 #include 文件也是如此,这些文件在您的源代码中有所命名...如果您修改字符名称的大小写,编译器不会抱怨,除非修改给您一个不存在的文件,并且在那个如果您会收到file not found 的投诉。

结论是:使用正确的名称,编译器将有准确的方式来拼写文件名....如果您不这样做,编译器将不会提供帮助... _如果您告诉我编译a.c我会告诉你__FILE__匹配a.c,即使实际文件名是A.C

可能编译器会给你不同的文件大小写,因为你给编译器不同的大小写(通过拼写错误的命令行或拼写错误的#include 指令)小心用例,你会收到正确的大小写在名称中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多