如何在 Windows 上从 C++11 统计信息对象的文件序列号中查找文件名
How to find the filename from a C++11 stat object's file serial number on Windows
因为在Windows中,使用Visual Studio,__FILE__
宏可以提供小写字符串,并且因为我需要知道正确大小写的文件名(用户认为),我正在尝试研究如何将Windows上的全小写路径转换为正确大小写的路径。
看起来使用统计信息获取有关文件的信息可能是一个很好的起点。
但是,给定一个统计对象,我如何才能获得文件名?
#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索引节点,而Windows上没有这样的东西。
所以这整个方法行不通。
还有其他选择吗?
恐怕你会再次陷入困境,因为这取决于用户如何调用编译器。如果你说(例如在一个制作文件中)
A.o: A.c
$(CC) A.c -o a.o
Windows 不会抱怨输出文件的大小写,因为这两种情况都引用相同的对象输出。 但A.c
的情况不同。 如果您尝试cc A.c
并且源文件作为a.c
存储在文件系统中,则只有一种方法可以知道文件存储在文件系统中的实际名称...即,在目录中搜索文件,并在找到与要搜索的文件匹配的文件时停止。 因此,这是一种复杂(且昂贵)的方式,因此编译器通常不会遵循它,因此它将根据您传递给它的名称进行操作。 对于#include
文件也是如此,这些文件在您的源代码中有些命名......我修改了字符名称的大小写,编译器不会抱怨,除非修改给你一个不存在的文件,在这种情况下,你会得到一个file not found
的投诉。
结论是:使用正确的名称,编译器将有确切的方式来拼写文件名。如果你不这样做,编译器不会在这方面提供帮助......_If你告诉我编译a.c
我会告诉你__FILE__
匹配a.c
,即使实际文件名是A.C
。
编译器可能会给你不同的文件大小写,因为你给编译器提供了不同的大小写(通过拼写错误的命令行或拼写错误的#include
指令)小心使用案例,并且您将收到名称中的正确大小写。
- 输入扑克牌的序列号(从0到35),并确定扑克牌的花色和尊严
- 如何在C++中动态生成带有序列号的文件名
- 需要忽略日期/序列号,但匹配字符串其余部分的正则表达式
- 来自本机的安卓 O 设备序列号
- USB序列号显示特殊字符
- 如何使用 /dev/xxx 路径中的C++获取 Ubuntu 中设备的 USB VID、PID 和序列号
- 如何在 Windows 上从 C++11 统计信息对象的文件序列号中查找文件名
- 获取主板的序列号
- 获取X509代码签名证书的序列号,以不受管理的C/C 签名
- 我正在尝试检索硬盘驱动器的序列号或电池标签
- C++ - 视窗 - BIOS 序列号 - 如何获取
- 如何在C或C 中获取主板地址或处理器ID /序列号
- c程序的Linux程序,以获取非根源用户的设备序列号
- 使用 WinRT 检索设备的序列号
- 头文件序列上的预处理器循环
- rand() 即使在我的 Mac 上播种时也会给出序列号
- 获取tcp数据包的序列号
- 处理器序列号
- 在一系列char*缓冲区中查找序列号
- 获取HD/分区序列号