C++ 通过删除点链接和重复斜杠规范化Unix文件路径

C++ 通过删除点链接和重复斜杠规范化Unix文件路径,c++,c,unix,C++,C,Unix,规范化Unix文件路径(即删除点链接和重复斜杠)的好方法是什么? 我既不需要也不想要符号链接解析。关于无链接解析的先决条件: 这会让事情变得更复杂(因为如果不是这样的话,你可以直接使用 它将断开包含链接的路径。例如,如果b是符号链接,则a/foo与a/foo不同。例如: a ┣ b (symlink to c/d) ┣ c ┳ d ┃ ┗ foo ┗ foo 在这种情况下,a/b/./foo实际上是a/c/foo,而纯粹基于文本的规范化将错误地认为它是a/foo 你真的确定你想要吗 如

规范化Unix文件路径(即删除点链接和重复斜杠)的好方法是什么?
我既不需要也不想要符号链接解析。

关于无链接解析的先决条件:

  • 这会让事情变得更复杂(因为如果不是这样的话,你可以直接使用
  • 它将断开包含链接的路径。例如,如果
    b
    是符号链接,则
    a/foo
    a/foo
    不同。例如:

    a
    ┣ b (symlink to c/d)
    ┣ c ┳ d
    ┃   ┗ foo
    ┗ foo
    
    在这种情况下,
    a/b/./foo
    实际上是
    a/c/foo
    ,而纯粹基于文本的规范化将错误地认为它是
    a/foo

你真的确定你想要吗

如果您这样做,那么您应该处理所有这些问题:

  • 空字符串(只返回“.”)
  • 多个初始斜杠:1或2,保持原样,除此之外,减少为1。也就是说,
    /a
    /a
    保持不变,但
    ///a
    ///a
    变为
    /a
    。有关说明,请参阅
  • 应删除空位(
    a//b
  • 应该删除点位(
    a//b
  • 现在是有趣的部分:双点。
    • 基本思想是删除前面的位。
      a/./b
      → <代码>a/b
    • 但如果它们一直向上延伸到初始斜杠,则应将其删除。例如
      /../a
      → <代码>/a和
      /a/../../../b
      → <代码>/b
    • 如果它们一直向上直到没有初始斜杠,则应保留额外的斜杠。例如
      。/a
      → <代码>。/a和
      a/../../../b
      → <代码>。/../b

如果建议您查看.grated中的normpath实现,它是python,但算法可读性很强。

关于无链接解析的先决条件:

  • 这会让事情变得更复杂(因为如果不是这样的话,你可以直接使用
  • 它将断开包含链接的路径。例如,如果
    b
    是符号链接,则
    a/foo
    a/foo
    不同。例如:

    a
    ┣ b (symlink to c/d)
    ┣ c ┳ d
    ┃   ┗ foo
    ┗ foo
    
    在这种情况下,
    a/b/./foo
    实际上是
    a/c/foo
    ,而纯粹基于文本的规范化将错误地认为它是
    a/foo

你真的确定你想要吗

如果您这样做,那么您应该处理所有这些问题:

  • 空字符串(只返回“.”)
  • 多个初始斜杠:1或2,保持原样,除此之外,减少为1。也就是说,
    /a
    /a
    保持不变,但
    ///a
    ///a
    变为
    /a
    。有关说明,请参阅
  • 应删除空位(
    a//b
  • 应该删除点位(
    a//b
  • 现在是有趣的部分:双点。
    • 基本思想是删除前面的位。
      a/./b
      → <代码>a/b
    • 但如果它们一直向上延伸到初始斜杠,则应将其删除。例如
      /../a
      → <代码>/a和
      /a/../../../b
      → <代码>/b
    • 如果它们一直向上直到没有初始斜杠,则应保留额外的斜杠。例如
      。/a
      → <代码>。/a和
      a/../../../b
      → <代码>。/../b

如果你建议你看正常路径实现,它是Python,但是算法不是C++。请选择一种语言。你想要什么?<代码> //Ur/bin///t////..·/Lb/opsSy///<代码>映射到/LIb/opsSsh (或者也许是代码>//LB/OpenSSH )还是只想在文本操作上?或者你想把它映射到<代码> /Ur/bin//tp/….. /LIB/OpenSSH < /Cord>?第二个路径映射仍然遍历任何的Syrink,所以可以说是更安全的。@奥拉夫两个标记都表示我不关心,我不需要关心,因为它们都应该用C++编译器工作。不一定。我写的是:C不是C++。它们是不同的语言,它们的语法相似,但有时也会有细微的差别。从C++中调用C编译代码通常都是经常工作的。C不是C++,请选择一种语言。你想要什么?<代码> ///rb/bin //tp//////../LIb/opsSy///<代码>映射到 /LIb/OpenSSH < /代码>(或者可能是

/../lib/openssh
)还是只想在文本操作上?或者你想把它映射到<代码> /Ur/bin//tp/….. /LIB/OpenSSH < /Cord>?第二个路径映射仍然遍历任何的Syrink,所以可以说是更安全的。@奥拉夫两个标记都表示我不关心,我不需要关心,因为它们都应该用C++编译器工作。不一定。我写的是:C不是C++。它们是不同的语言,它们语法相似,但是有时对于相同的语法也有细微的差别。从C++调用C编译的C代码通常都是经常工作的。谢谢解释。我可能会处理到潜在的不存在对象的路径,所以部分规范化的RealPoad会是理想的,但是我想。ess我将简单地规范化在没有FS信息的情况下可以规范化的内容(连续的斜杠“./”),然后尝试调用
realpath
,该调用要么成功,要么失败。(这适用于基于系统调用的依赖项跟踪器——对不存在的文件的请求仍然会创建依赖项,并且这些依赖项应该进行某种程度的规范化和重复数据消除)有道理。您可能应该在代码文档的某个地方提到,不允许依赖项中包含符号链接。无论如何都不需要,这样可以避免主要的陷阱。感谢您的解释。我可能正在处理指向/通过可能不存在的对象的路径,因此部分规范化realpath是理想的,但我我想我将简单地规范化c