我有一个字符串,我想使用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