// ïåðåâîäèì åãî â ÷èñëî
sscanf(hex,"%X",&code);
// è çàïèñûâàåì îáðàòíî â ñòðîêó
*p++=(char)code;
// óêàçàòåëü p âñåãäà îòìå÷àåò òî ìåñòî â ñòðîêå, â êîòîðîå
// áóäåò ïîìåùåí î÷åðåäíîé äåêîäèðîâàííûé ñèìâîë
}
// èíà÷å, åñëè ýòî "+", òî çàìåíÿåì åãî íà " "
else if(*st=='+') *p++=' ';
// à åñëè íå òî, íè äðóãîå — îñòàâëÿåì êàê åñòü
else *p++=*st;
} while(*st++!=0); // ïîêà íå íàéäåì íóëåâîé êîä
}
Функция основана на том свойстве, что длина декодированных данных всегда меньше, чем кодированных, а значит, всегда можно поместить результат в ту же строку, не опасаясь ее переполнения. Конечно, примененный алгоритм далеко не оптимален, т. к. использует довольно медлительную функцию sscanf() для перекодирования каждого символа. Тем не менее, это самое простое, что можно придумать, вот почему я так и сделал.