c-当使用sprintf时,如何处理字符串中的百分比符号



我有一个字符串,我想使用sprintf将其添加到缓冲区

https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20220728%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220728T121916Z&X-Amz-Expires=300&X-Amz-Signature=fb5d8ebe7ec4f63d462d76f059a22402ec4e9931e1b9278a739dbc0c617aedbb&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment%3B%20filename%3DQuasar.v1.4.0.zip&response-content-type=application%2Foctet-stream

我用

FILE *p;
char url[] = "https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20220728%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220728T121916Z&X-Amz-Expires=300&X-Amz-Signature=fb5d8ebe7ec4f63d462d76f059a22402ec4e9931e1b9278a739dbc0c617aedbb&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment%3B%20filename%3DQuasar.v1.4.0.zip&response-content-type=application%2Foctet-stream";
sprintf(request, "%s %s %s", "GET", url, "HTTP/1.1"); 
p = fopen("out.txt" , "w");
fprintf(p , request);
fclose(p);

这导致out.txt中的字符串格式不正确

GET https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A0.000000202207280.000000us-east-10.000000s30.000000aws4_request&X-Amz-Date=20220728T121916Z&X-Amz-Expires=300&X-Amz-Signature=fb5d8ebe7ec4f63d462d76f059a22402ec4e9931e1b9278a739dbc0c617aedbb&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment%3B            0.000000ilename%3DQuasar.v1.4.0.zip&response-content-type=application0.000000octet-stream HTTP/1.1   

在CCD_ 3中存在空间间隙%3B%20filename->%3B 0.000000ilename

我有什么解决方法可以将url复制到缓冲区,有没有一种方法可以转义像%20f这样的字符串,并在它们上循环,然后再次从url解码为ascii

我将请求缓冲区输出到文本文件只是为了检查输出,因为终端没有正确显示问题

解决方案非常简单:

fprintf(p , "%s", request);

基本上,永远不要将要输出的字符串用作格式。使用正确的格式显示字符串

由于request是您想要发送的结果,所以不要将其用作格式化字符串。使用设计为按原样发送字符串的功能,fputs:

fputs(request, p);

如果这还不能解决所有问题,我怀疑request不够大,无法容纳sprintf的字符串。请使用snprintf进行确认。如果request是一个自动变量,只需与sizeof request:进行比较

int len = snprintf(request, sizeof request, "%s %s %s", "GET", url, "HTTP/1.1");
if((unsigned) len >= sizeof request || len < 0) {
printf("%d >= %zu or < 0n", len, sizeof request);
exit(1);
}

您的问题与转义%字符有关,您应该创建一个带有循环的函数,该循环遍历缓冲区的字符并检查其中是否有%。在这种情况下,它应该添加%,然后添加原始%以转义该字符,然后继续,直到完成所有缓冲区

void esc(char * old, char * new)
{
int old_size = strlen(old), i=0,j=0;
while ( i < old_size)
{
if (old[i] == '%')
{
new[j] = '%';
j++;
new[j] = old[i];    
}
new[j] = old[i];
i++,j++;
}
new[j] = '';
}

int main()
{
char new[1024]; 
char buffer[4096];
char link[] = "https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20220728%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220728T132853Z&X-Amz-Expires=300&X-Amz-Signature=8de49cce44acb53aff3a2d284cd402f4b1a7cd6fa9335ec7c8be5b3a5d96d24c&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment%3B%20filename%3DQuasar.v1.4.0.zip&response-content-type=application%2Foctet-stream";
esc(link , new);
sprintf(buffer , "%s %s HTTP/1.1", "GET", new);
printf("%sn", buffer);
return 0;
}

最终结果看起来像这个

GET https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%%2F20220728%%2Fus-east-1%%2Fs3%%2Faws4_request&X-Amz-Date=20220728T132853Z&X-Amz-Expires=300&X-Amz-Signature=8de49cce44acb53aff3a2d284cd402f4b1a7cd6fa9335ec7c8be5b3a5d96d24c&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment%%3B%%20filename%%3DQuasar.v1.4.0.zip&response-content-type=application%%2Foctet-stream HTTP/1.1

最新更新