What does the path need to look like for boost::canonical to work?

Why does boost::filesystem::canonical give error on this?

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>
#include <boost/filesystem.hpp>

using namespace std;

int main()
{
    string example_path = "D:\\Portables\\REAPER\\_TEST PROJECT\\..\\name.wav";
    string actual_path = boost::filesystem::canonical(example_path).string();
}


The path in question exists on my computer (obviously it will fail if you run code on cpp).

Maybe I am confused as to how canonical() expects the path to be formatted. Could you give an example path that would work with canonical?
Last edited on
What error does it give?

for example, on my linux box, it throws an exception saying

boost::filesystem::canonical: No such file or directory: "/home/cubbi/D:\Portables\REAPER\_TEST PROJECT\..\name.wav"

and here using Visual Studio in an online compiler http://rextester.com/JUI81102
it says boost::filesystem::canonical: No such file or directory: "D:\Portables\REAPER\_TEST PROJECT\..\name.wav"
Last edited on
Ok, that is the error I am getting.

So, name.wav is in _TEST_PROJECT

wouldn't the .. be REAPER? It's one folder up, which would be REAPER.
Last edited on
omg wait a minute... is canonical expecting the name.wav to be there?
yes that is the reason........ Cubbi, thanks for your help.
Last edited on
wait a minute wait wait wait... this is not resolved. I need to convert .. to actual path and the path may not exist. What am I to do? I am making a multiplatform program. Can I assume every .. is just "remove the previous folder in path"? I could make a simple string parsing function for that and not use canonical at all.
Last edited on
JUMP past drive letter

D:\Software\Portables\..\REAPER\..\..\..\_TEST PROJECT\..\name.wav

SAVE in buffer until encounter \ . . \
REPLACE from buffer position start to end - 1

\Software\\Portables\..\REAPER\..\..\..\_TEST PROJECT\..\name.wav -> CONTINUE

\Software\REAPER\..\..\..\_TEST PROJECT\..\name.wav -> CONTINUE

\Software\..\..\_TEST PROJECT\..\name.wav -> CONTINUE

\..\_TEST PROJECT\..\name.wav -> ERROR

1
2
3
4
5
6
7
8
9
10
11
D:\Portables\REAPER\_TEST PROJECT\..\name.wav -> D:\Portables\REAPER\name.wav

D:\Portables\REAPER\..\_TEST PROJECT\name.wav -> D:\Portables\_TEST PROJECT\name.wav

D:\Portables\REAPER\..\..\_TEST PROJECT\name.wav -> D:\_TEST PROJECT\name.wav

D:\Portables\REAPER\..\..\_TEST PROJECT\..\name.wav -> D:\name.wav

D:\Portables\..\REAPER\..\..\_TEST PROJECT\..\name.wav -> (!!ERROR!!) D:\..\name.wav

D:\Portables\REAPER\_TEST PROJECT\name.wav\.. -> (STILL GOOD) D:\Portables\REAPER\_TEST PROJECT\
Last edited on
why "a simple string parsing function" if you have boost.filesystem already?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <boost/filesystem.hpp>
#include <vector>
#include <iostream>

namespace fs = boost::filesystem;
int main()
{
    std::vector<fs::path> v = {
       "D:\\Portables\\REAPER\\_TEST PROJECT\\..\\name.wav",
       "D:\\Portables\\REAPER\\..\\_TEST PROJECT\\name.wav",
       "D:\\Portables\\REAPER\\..\\..\\_TEST PROJECT\\name.wav",
       "D:\\Portables\\REAPER\\..\\..\\_TEST PROJECT\\..\\name.wav",
       "D:\\Portables\\..\\REAPER\\..\\..\\_TEST PROJECT\\..\\name.wav",
       "D:\\Portables\\REAPER\\_TEST PROJECT\\name.wav\\.."};

    for(fs::path p: v) {
        std::cout << p << " -> ";
        fs::path root = p.is_absolute() ? p.root_path() : absolute(p).root_path();
        fs::path result;
        for(fs::path f: absolute(p)) {
            if(f == ".") {
                continue;
            } else if(f == "..") {
                if(result == root) {
                    result.clear();
                    break;
                } else {
                   result.remove_filename();
                }
                continue;
            } else {
                result /= f;
            }
        }
        std::cout << result << '\n';
    }
}


live demo: http://rextester.com/IDXG70343

"D:\Portables\REAPER\_TEST PROJECT\..\name.wav" -> "D:/Portables\REAPER\name.wav"
"D:\Portables\REAPER\..\_TEST PROJECT\name.wav" -> "D:/Portables\_TEST PROJECT\name.wav"
"D:\Portables\REAPER\..\..\_TEST PROJECT\name.wav" -> "D:/_TEST PROJECT\name.wav"
"D:\Portables\REAPER\..\..\_TEST PROJECT\..\name.wav" -> "D:/name.wav"
"D:\Portables\..\REAPER\..\..\_TEST PROJECT\..\name.wav" -> ""
"D:\Portables\REAPER\_TEST PROJECT\name.wav\.." -> "D:/Portables\REAPER\_TEST PROJECT"
Thanks! resolved.
Topic archived. No new replies allowed.