百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

C++ 为path类专门化std::formatter

yuyutoo 2024-10-18 12:16 1 浏览 0 评论


path类在文件系统库中被用来表示文件或目录路径。在POSIX兼容系统(如macOS和Linux)上,path对象使用char类型来表示文件名。在Windows上,path使用wchar_t。在Windows上,cout和format()不会显示wchar_t字符的原始字符串。这意味着没有简单的即用型方法来编写跨POSIX和Windows的可移植代码,这些代码使用了文件系统库。

我们可以使用预处理器指令为Windows编写特定的代码版本。对于某些代码库来说,这可能是一个合理的解决方案,但对于本书来说,这样做既混乱又不符合简单、可移植、可重用示例的目的。

优雅的解决方案是为path类编写一个C++20 formatter专门化。这允许我们以简单和可移植的方式显示path对象。

如何做……

在本示例中,我们将为fs::path类编写一个formatter专门化:

首先,为了方便起见,我们使用一个命名空间别名。所有文件系统名称都在std::filesystem命名空间中:

namespace fs = std::filesystem;


我们为path类编写的formatter专门化简单且简洁:

template<>  
struct std::formatter<fs::path>: std::formatter<std::string> {  
    template<typename FormatContext>  
    auto format(const fs::path& p, FormatContext& ctx) {  
        return format_to(ctx.out(), "{}", p.string());  
    }  
};


在这里,我们为fs::path类型专门化了formatter,使用其string()方法来获取可打印的表示形式。我们不能使用c_str()方法,因为它在Windows上与wchar_t字符不兼容。

本书中第1章“新的C++20特性”中有对formatter专门化的更完整解释。

在main()函数中,我们使用命令行传递文件名或路径:

int main(const int argc, const char** argv) {  
    // ... 省略了检查参数数量的代码 ...  
  
    fs::path dir{ argv[1] };  
  
    if(!fs::exists(dir)) {  
        cout << format("path: {} does not exist\n", dir);  
        return 1;  
    }  
  
    cout << format("path: {}\n", dir);  
    cout << format("filename: {}\n", dir.filename());  
    cout << format("cannonical: {}\n", fs::canonical(dir));  
}


argc和argv参数是标准的命令行参数。

argv[0]始终是可执行文件本身的完整目录路径和文件名。如果我们没有正确数量的参数,我们将显示argv[0]的文件名部分作为用法消息的一部分。

在这个示例中,我们使用了一些文件系统函数:

- fs::exists()函数检查目录或文件是否存在。

- dir是一个path对象。我们现在可以直接将它传递给format(),使用我们的专门化来显示路径的字符串表示形式。

- filename()方法返回一个新的path对象,我们直接将其传递给format(),使用我们的专门化。

- fs::canonical()函数接受一个path对象,并返回一个新的path对象,其中包含规范的绝对目录路径。我们将此path对象直接传递给format(),它显示从canonical()返回的目录路径。

输出示例:

$ ./formatter ./formatter.cpp  
path: ./formatter.cpp  
filename: formatter.cpp  
cannonical: /home/billw/working/chap10/formatter.cpp


它是如何工作的……

fs::path类在文件系统库中被用来表示目录路径和文件名。通过提供formatter专门化,我们可以轻松地在不同平台上一致地显示path对象。

path类提供了一些有用的方法。我们可以遍历一个路径来查看其组成部分:

fs::path p{ "~/include/bwprint.h" };  
cout << format("{}\n", p);  
for(auto& x : p) cout << format("[{}] ", x);  
cout << '\n';


迭代器返回路径中每个元素的path对象。

我们还可以获取路径的不同部分:

fs::path p{ "~/include/bwprint.h" };  
cout << format("{}\n", p);  
cout << format("{}\n", p.stem());  
cout << format("{}\n", p.extension());  
cout << format("{}\n", p.filename());  
cout << format("{}\n", p.parent_path());


在本章中,我们将继续使用这个为path类编写的formatter专门化。

相关推荐

Google Chrome 100 Beta发布 用户代理字符串作用开始逐渐降低

GoogleChrome和MozillaFirefox都在迅速接近100版本,这有可能破坏一些错误识别浏览器版本的网站(可能导致访问不正常,这有点类似于众所周知的千年虫)。两种浏览器都在研究可能的...

如何在Chrome,Edge,Safari和Firefox中更改用户代理

无论您是SEO,营销人员还是Web开发人员,通常都可能需要更改浏览器的用户代理以测试其他内容。例如,您正在运行特定于MAC-OS的活动。要确定您的广告系列是否正常运行并且未针对Linux用户,更改浏览...

Mozilla正在测试新的浏览器UserAgent

Mozilla最近发布了一个实验项目来测试3位数的UserAgent版本“Firefox/100.0”会不会让一些网站停止正常工作。浏览器UserAgent是一串字符串,里面包含了浏览器的软件信息,版...

爬虫与User-Agent

什么是User-Agent呢?User-Agent是一个特殊字符串头,被广泛用来标示浏览器客户端的信息,使得服务器能识别客户机使用的操作系统和版本,CPU类型,浏览器及版本,浏览器的渲染引擎,浏览器...

让你的浏览器充满魔性——User Agent Switche

对于前端人员,闲暇时就会研究各种插件,今天我就分享UserAgentSwitcher在Firefox和Chrome的使用情况。一、Firefox浏览器UserAgentSwitcher作为火...

亚马逊账号运营安全-浏览器指纹识别之User-Agent开篇

UA包含了一个约定的特征字符串。主要是面向受访问网络表明自己的操作系统,软件开发商,版本,应用类型等信息。这是一种主动暴露信息的方式。我们来看关于UA的简单语法定义:User-Agent:<p...

【每日学习】Python爬虫之伪装浏览器User-Agent

【主题】Python爬虫之伪装浏览器原理【分析】1.创建自定义请求对象的目的,对抗网站的反爬虫机制2.反爬虫机制1:判断用户是否是浏览器访问(User-Agent)3.对抗措施1:伪装浏览器进行访问【...

亚马逊账号运营安全-浏览器指纹识别之User-Agent二篇

大家好,上一篇亚马逊账号运营安全-浏览器指纹识别之User-Agent开篇为大家阐述了原理。下面是作者为大家整理的其他几个主流浏览器的UA配置。一下都是Windows1064X系统下整理。Chrom...

常见的爬虫UserAgent

通过前面的文章我们知道,UserAgent(用户代理)是HTTP请求的一部分,用于告诉服务器发起请求的客户端类型和属性等信息。同时,也了解了常见的UserAgent。...

HTTP请求头之User-Agent

什么是User-AgentUser-Agent中文名为用户代理,简称UA,...

你想不到的浏览器流氓史!那些奇怪的User-Agent,是这么来的...

平时我们用chrome浏览器做开发测试。Chrome的Useragent字段怎么这么奇怪?...

谷歌宣布 Chrome 将逐步停止支持 User Agent

谷歌近日宣布将放弃对Chrome浏览器中用户代理字符串(User-AgentString)的支持。取而代之的是,Chrome将提供一个名为“客户端提示(ClientHints)”的新API...

数据采集-用户代理(useragent)

UserAgent分类:PC端的UserAgent。移动端UserAgent。使用UserAgent的必要性:在写python网络爬虫程序的时候,经常需要修改UserAgent,有很多原因,罗列几个如...

如何获取当前浏览器的useragent

有时候,我们需要得到浏览器的useragent,从而再进行后面的一系列判断,返回不同的值。网上有说,在浏览器地址栏输入:javascript:alert(navigator.userAgent)这种方...

User Agent 解析:它是什么以及如何修改

什么是UserAgent?UserAgent,简称UA,是一个使服务器能够识别用户使用的浏览器类型、版本以及运行浏览器的操作系统等信息的字符串。它作为浏览器请求头部信息的一部分发送给服务器,以便服务...

取消回复欢迎 发表评论: