我需要使用查詢引數和不同的 API 端點構建一個 url。我不喜歡使用固定大小的 char 陣列,因為記憶體被浪費了,我依賴于希望大小足夠大。
#define BASE_URL "https//mydomain.com/api/"
#define ID "ID1"
char* do_endpoint_request(const char* param)
{
char url[500];
snprintf(url, sizeof(url), BASE_URL "endpoint?id=%s¶m1=%s", ID, param);
// do request with url ...
}
如何改進此代碼,該記憶體是使用注入的字串和引數的確切大小動態分配的?
uj5u.com熱心網友回復:
您可以使用可以使用 NULL 而不是實際緩沖區呼叫的事實,snprintf()并且它回傳如果有足夠空間則將創建的字串的長度。所以:
#define BASE_URL "https//mydomain.com/api/"
#define ID "ID1"
char* do_endpoint_request(const char* param)
{
int len;
len = snprintf(NULL, 0, BASE_URL "endpoint?id=%s¶m1=%s", ID, param);
char url[len 1]; // len excludes NULL; use malloc() if you can't use VLA
// sprintf() is ok now, url is guaranteed to be large enough
sprintf(url, BASE_URL "endpoint?id=%s¶m1=%s", ID, param);
// do request with url ...
}
uj5u.com熱心網友回復:
也許你需要這樣的東西:
char* do_endpoint_request(const char* param)
{
int sizeneeded = snprintf(NULL, 0, BASE_URL "endpoint?id=%s¶m1=%s", ID, param);
char url[sizeneeded 1];
sprintf(url, BASE_URL "endpoint?id=%s¶m1=%s", ID, param);
// do request with url ...
}
但是,如果字串param的大小是“合理的”,那么像您的示例中這樣的區域變數就足夠了。
但是,您可能應該對 進行完整性檢查param,以確保它的長度具有合理/合理的大小。否則,所有方法都可能以未定義的行為結束:
- 在您的原始代碼中:如果
param太長,url陣列將太小,您將獲得未定義的行為。 - 在這個答案中建議的代碼中:如果
param太長(可能長到幾千,取決于您的平臺和其他因素),char url[sizeneeded];可能不會很好地結束,您會得到未定義的行為。
uj5u.com熱心網友回復:
在這種情況下,我們需要引數的大小。
char* do_endpoint_request(const char* param, int param_size)
{
char* url = calloc(param_size <size of base url>, sizeof(char));
snprintf(url, sizeof(url), BASE_URL "endpoint?id=%s¶m1=%s", ID, param);
// do request with url ...
}
諸如此類的東西應該可以正常作業,但是可能需要更改分配的大小。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/443116.html
上一篇:通過正則運算式從記事本 中相同型別的URL中提取所需部分
下一篇:Django重定向到第二個URL
