Herman said:
Hi,
Hello!
Can you please tell me if there is a library function
in C++/C to do URL decoding?
i.e. change from:
http%3A%2F%2F
to:
http://
There is no *standard* library facility to do that.
There's almost certainly libraries out there that have
that facility, though. Google for "C++ URL library" or
similar searches.
However, it may be simpler to just to write your own.
Here's a big hint: Unix file names may only contain certain
characters, not others; so Unix tends to turn unacceptable
characters into 3-character triglyphs consisting of "%"
followed by the two-digit ASCII value of the character,
in hexidecimal. (Or, if the numbers are greater than %7E,
they're probably ISO-8859-1 instead of ASCII.)
Examples:
* = %2A (as in "grep 'dog' *") // ASCII
/ = %2F (as in "user/bin") // ASCII
§ = %A7 (as in "see §38.7.13") // assuming ISO-8859-1
ñ = %F1 (as in "España") // assuming ISO-8859-1
(Google "ASCII" and "ISO-8859-1" for more on these encodings.)
So just replace each %HH with the character who's encoding
is "HH". Eg: "%64%6F%67" becomes "dog".
Grab each "%XY" using std::string.find() and std::string.substr().
Feed each "%XY" substring into a function that returns the
character with that encoding. Then replace the "%XY" in the string
with the character Z which you just generated, by using
std::string.replace().
Here's a program I just wrote, for the fun of it, which solves
your problem (tested, working code). (CAVEAT: This assumes that
any '%' character will be followed by a valid two-digit hexidecimal
number. If not, it will blow up. You'll have to add your own
error-checking.)
// dehex.cpp
#include <iostream>
#include <string>
#include <sstream>
char CharFromHex (std::string a)
{
std::istringstream Blat (a);
int Z;
Blat >> std::hex >> Z;
/*
int X = int (a[1]); // 16^1 place value
if (X >= 97) {X -= 97;} // capital letter?
else if (X >= 65) {X -= 65;} // small letter?
else {X -= 48;} // numeral?
int Y = int (a[2]); // 16^0 place value
if (Y >= 97) {Y -= 97;} // capital letter?
else if (Y >= 65) {Y -= 65;} // small letter?
else {Y -= 48;} // numeral?
int Z = 16 * X + Y; // generate numerical value of character
*/
return char (Z); // cast to char and return
}
int main (int Beren, char * Luthien[])
{
std::string Text (Luthien[1]);
std::string::size_type Pos;
std::string Hex;
while (std::string::npos != (Pos = Text.find('%')))
{
Hex = Text.substr(Pos + 1, 2);
Text.replace(Pos, 3, 1, CharFromHex(Hex));
}
std::cout << Text << std::endl;
return 0;
}
You're welcome.