Win32 C - append Url to path



  • This has been driving me nuts for the past hour or two. Can somebody tell me the proper way to append a URL to a file path in vanilla Win32 C? I.e. append "www.whatever.com/omgwtf/lol.html" to "C:\asdf" to get "C:\asdf\www.whatever.com\omgwtf\lol.html" using Path*/Url*/other functions? I don't think it can be done without looping through the string yourself. It needs to be all backslashes or else CreateDirectory/CreateFile will fail, and as far as I can tell none of the functions will automatically convert the forward slashes to back slashes.



  • If you're using CString, use its Replace function. If not then yes, you need to do it yourself.



  • @kcwong said:

    If you're using CString, use its Replace function. If not then yes, you need to do it yourself.

    Er... CString is MFC. He asked about Win32.

    I don't know of any Win32 URL/URI specific functions offhand, but I don't claim to be very strong with Win32 -- I prefer C# or Java.

    That said, you could always concatenate with the StringCBCat function.



  • @luke727 said:

    This has been driving me nuts for the past hour or two. Can somebody tell me the proper way to append a URL to a file path in vanilla Win32 C? I.e. append "www.whatever.com/omgwtf/lol.html" to "C:\asdf" to get "C:\asdf\www.whatever.com\omgwtf\lol.html" using Path*/Url*/other functions? I don't think it can be done without looping through the string yourself. It needs to be all backslashes or else CreateDirectory/CreateFile will fail, and as far as I can tell none of the functions will automatically convert the forward slashes to back slashes.

    Hmmm... I'm pretty sure a lot of the Windows API will happily let you use / as a path seperator. I could be wrong, though.



  • It's funny because I could have sworn that they used to take / as a path separator (I may be delusional).  But whenever I try to open a file using / instead of \ it gives me an "invalid path" error.  If I use \ then it works.  Maybe it's just the C++ wrappers that automatically convert the path to use the correct separator before calling the low-level functions.  I think C# will work with either separator as well.  I guess I will have to take it upon myself to make sure the right separator is being used.



  • I'm all for using available functionality, but sometimes, the search isn't worth it.  If I can't find it in a reasonable amount of time, and no one else can, either, then I'll just roll my own solution.  Since what you need is just a loop to replace one character with another, I'd just write it and be done with it.



  • "C:\asdf\www.whatever.com\omgwtf\lol.html"

    You have folders named like full domain names?



  • @dhromed said:

    "C:\asdf\www.whatever.com\omgwtf\lol.html"

    You have folders named like full domain names?


    Doesn't sound too unreasonable for someone who works on many projects concurrently.



  • Or someone using/writing a site mirroring program.



  • Yes, it is related to mirroring websites; I do not do any kind of webpage development, if that's what you were thinking.



  • Okay. :)

    It's just not too common, and I have a silly thing against periods in a filename.



  • Re: the win32 API - depends which part of the API you're talking about, and which version. The API is a WTF in itself - it does things about every possible way, using about every possible convention you've heard of, all arbitrarily.
    The answer is: some functions will take / and be fine, some won't, and only \ is actually supported.

    As for concatenating strings, remember the win32 api is in C. There are no strings in C, just pointers to sequences of bytes. I'd say to take advantage of the STL as you're probably using C++, but std::string doesn't have a replace either.
    It's pretty trivial to replace one char with another though, so just write yourself a small slash_replace function, use strcat, and next time don't use C for string processing :-)



  • Yes, the Win32 API is pure joy to work with.[:D]

    Anyway, this wasn't my project; I inherited it.  I switched things up and changed everything to use CStrings instead of plain character arrays.  It took a while to do, but life is easier now.



  • You'll need a transformation that mangles slashes:

    char mangle_slash (char c) {
      if (c == '\\')
        return '/';
      return c;
    }
    std::string path = "C:\\Windows\\";
    std::string fragment = "www.example.com/foo/bar";
    
    std::string output = path;
    std::transform (fragment.begin (),
                    fragment.end (),
                    std::back_inserter (output),
                    mangle_slash);

    Completely untested. I've probably goofed up the back_inserter or the forum formatting.



  • Figures I'd goof up the logic.

    char mangle_slash (char c) {
      if (c == '/')
        return '\\';
    
      return c;
    }


  • @Angstrom said:

    You'll need a transformation that mangles slashes:

    char mangle_slash (char c) {
      if (c == '\\')
        return '/';
      return c;
    }
    std::string path = "C:\\Windows\\";
    std::string fragment = "www.example.com/foo/bar";
    
    std::string output = path;
    std::transform (fragment.begin (),
                    fragment.end (),
                    std::back_inserter (output),
                    mangle_slash);

    Completely untested. I've probably goofed up the back_inserter or the forum formatting.


    He said he needs to use C, but your basic logic works.

    Replacing every character seems an odd way to do a simple replace, though.  It's kind of odd that C++ has a transform, but not a replace (in string).  Again with the over-engineering.



  • You mean replace_if in <algorithm>?

    I used transform to merge the 'replace slashes' and 'append strings' into one step, but you don't have to do it that way.


Log in to reply