我想写一个函数:
inline char separator()
{
/* SOMETHING */
}
在标准 C/C++/C++11 中返回系统的文件分隔符?(我的意思是斜杠或反斜杠,具体取决于系统)。有没有办法做到这一点?
我想写一个函数:
inline char separator()
{
/* SOMETHING */
}
在标准 C/C++/C++11 中返回系统的文件分隔符?(我的意思是斜杠或反斜杠,具体取决于系统)。有没有办法做到这一点?
除了检查 ifdefs 之外,我不知道该怎么做
inline char separator()
{
#ifdef _WIN32
return '\\';
#else
return '/';
#endif
}
或(由 PaperBirdMaster 建议)
const char kPathSeparator =
#ifdef _WIN32
'\\';
#else
'/';
#endif
如果您的编译器提供 c++17 功能,那么您可以使用std::filesystem::path::preferred_separator
根据您的平台生成首选分隔符字符的方法。例如,在 Windows 上这通常是\
,而在 Linux 上你会得到/
.
有关更多信息,请参阅此。
这个问题确实暗示了一个更棘手的问题。
如果您只关心 UNIX 与 Winodws 并且只关心目录和文件,那么您已经看到的(大部分)将起作用,但是将路径名拼接到其组件中的更一般的问题是一个更丑陋的问题。根据平台,路径可能包括以下一项或多项:
虽然为此有 3rd 方库(如各种 CPAN Perl 模块、Boost 等),并且每个操作系统都包含为此的系统功能,但 C 没有为此内置任何内容,C++ 标准仅获得了此功能(通过合并Boost 模块)在 2017 年。
此类函数可能需要处理的一些示例是:
还有很多其他的。
值得注意的是,C++17 文件系统库并未涵盖所有这些可能性。它std::filesystem::path
由一个可选的根名称(卷标识符)、一个可选的根目录(用于标识绝对路径)和一系列由目录分隔符分隔的文件名组成。这涵盖了在 UNIX 平台上可能有效的所有内容以及其他平台的大多数用例,但并不全面。例如,它不支持子流(依靠操作系统以某种方式将它们映射到文件名上——这是由 Mac OS X 完成的,但不是经典的 MacOS)。它也不包括对文件版本号的支持。
另请参阅Wikipedia 关于 Path和 C++17 std::filesystem::path类的条目
http://en.cppreference.com/w/cpp/filesystem
我建议你看看你想用目录分隔符做什么(提取基本名称,将路径分解为目录列表等)并编写一个函数来做到这一点。如果您使用的是 C++17(并且您确定您的代码不会被 17 之前的 C++ 编译器编译),那么您可以(可能)使用标准 C++ 库代码来编写此函数的可移植实现。如果没有,该功能将需要为#ifdef
您将支持的每个平台使用特定于平台的 s,使用#error
if none of the conditions are meet,强制您为意外平台添加条件。
或者使用包含所有这些功能的第 3 方库(如 Boost),如果这是可以接受的。
可能是这样的
#if defined(WIN32) || defined(_WIN32)
#define PATH_SEPARATOR "\\"
#else
#define PATH_SEPARATOR "/"
#endif
接受的答案在 Cygwin 下不起作用。在 Windows 上运行的 Cygwin 编译程序可以使用 Windows 样式的 '\' 分隔符,但它没有定义 _WIN32 等。在 Cygwin 下工作的修改后的解决方案:
inline char separator()
{
#if defined _WIN32 || defined __CYGWIN__
return '\\';
#else
return '/';
#endif
}
或者
const char kPathSeparator =
#if defined _WIN32 || defined __CYGWIN__
'\\';
#else
'/';
#endif
std::filesystem::path::preferred_separator
现在应该被用作一个干净的C++17
库函数,看起来如何。
我很惊讶没有人提供以下内容。这建立在其他人在这里提供的基础之上。
尽管在此示例中,我试图动态获取正在运行的可执行文件的名称以供使用,但根据需要进行跳转并重新应用它并不难。
Windows 使用正斜杠来表示参数。因此,您可以在第一个参数中首先检查它argv[0]
,其中包含正在运行的程序的名称。
请注意,以下结果会剥离最后一个斜杠之前的路径名,留下sepd
程序的文件名。
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[]){
//int a = 1
//int this = (a == 1) ? 20 : 30; //ternary operator
//is a==1 ? If yes then 'this' = 20, or else 'this' = 30
char *sepd = (strrchr(argv[0], '\/') != NULL) ?
strrchr(argv[0], '\/') :
strrchr(argv[0], '\\');
printf("%s\n\n", sepd);
printf("usage: .%s <host> \n\n", sepd);
while (getchar() != '\n');
}
但实际上,这是相当肮脏的,而且随着 Windows 最近加入 Bash(此时尚未实现)的举措,这可能会产生意想不到或意想不到的结果。
它也不像其他人提供的那样理智和不受错误影响,尤其是#ifdef _WIN32
.