Date: 2011jun25
Update: 2026sep25
Language: C/C++
Q. C/C++: Encode a file name for a URL
A. Here are two routines that can do that:
// Helper function
inline char * Shuffle(char * dest, const char * src) {
return (char *) memmove(dest, src, strlen(src) + sizeof(char));
}
void EncodeForUrl(char * s) {
char szHex[] = "%??"; // We depend on the percent symbol at szHex[0]
const int lenHex = strlen(szHex);
if (s == NULL) return;
for (char * p = s; *p;) {
if (isalnum(*p)) {
p++;
}
else {
Shuffle(p+lenHex, p+1);
sprintf(szHex+1, "%02X", *p);
memcpy(p, szHex, lenHex);
p += lenHex;
}
}
}
// Turn %3A into colon, and %5C into backslash, etc
void DecodeFromUrl(char * s) {
char szHex[] = "??"; // We depend on the NUL character at szHex[2]
char * dummy;
if (s == NULL) return;
for (char * p = s; *p; p++) {
if (*p == '%') {
szHex[0] = p[1];
szHex[1] = p[2];
*p = (char) strtol(szHex, &dummy, 16);
Shuffle(p+1, p+3);
}
}
}
Full Example:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
// (Place above functions here)
#ifndef MAX_PATH
#define MAX_PATH (256)
#endif
int main() {
// Make a URL with a filename
char filename[MAX_PATH] = "c:\\windows\\fonts\\arial.ttf";
char url[MAX_PATH*3];
printf(" filename=%s\n", filename);
EncodeForUrl(filename);
printf("encoded filename=%s\n", filename);
snprintf(url, sizeof(url), "dosomething.cgi?filename=%s", filename);
printf("url=%s\n", url);
}
Output:
filename=c:\windows\fonts\arial.ttf
encoded filename=c%3A%5Cwindows%5Cfonts%5Carial%2Ettf
url=dosomething.cgi?filename=c%3A%5Cwindows%5Cfonts%5Carial%2Ettf