You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用sprintf时如何处理字符串中的百分号符号

问题描述

需要将以下URL通过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中字符串出现畸形,例如%3B%20filename变为%3B 0.000000ilename,%2F变为0.000000。需要在无需循环解码URL的情况下,转义%20f这类字符串,以正确将URL复制到缓冲区。

解决方法

问题根源是sprintf和fprintf这类格式化函数会把字符串中的%当成格式占位符解析。比如%20f会被识别为宽度为20的浮点数格式符,而代码中没有对应参数,所以会输出随机浮点数(如0.000000),导致URL被破坏。

有两种简单的解决方式:

方式一:直接拼接字符串,避免使用格式化函数

如果只是简单拼接"GET "、URL和" HTTP/1.1",可以用strcpy和strcat组合,完全绕过格式化解析:

FILE *p;
char url[] = "你的URL内容";
// 确保request缓冲区足够大,能容纳所有内容
strcpy(request, "GET ");
strcat(request, url);
strcat(request, " HTTP/1.1");

p = fopen("out.txt" , "w");
fputs(request, p); // 用fputs而非fprintf,避免再次解析格式符
fclose(p);

方式二:转义URL中的所有%为%%

格式化函数中,%%会被解析为单个%输出。只需把URL里的每个%替换成%%,sprintf就不会把它们当成格式占位符:

FILE *p;
// 注意把原URL中的%替换为%%
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";
// 建议用snprintf避免缓冲区溢出
snprintf(request, sizeof(request), "%s %s %s", "GET", url, "HTTP/1.1"); 

p = fopen("out.txt" , "w");
fputs(request, p);
fclose(p);

内容的提问来源于stack exchange,提问作者sinister

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:24:18