我正在编写一个HTTP 1.0下载程序,并使用以下#define替换格式来格式化查询:
#define GET_FORMAT "GET %s%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: getter\r\n\r\n"
#define HEAD_FORMAT "HEAD %s%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: getter\r\n\r\n"
#define GET_FORMAT_RANGE "GET %s%s HTTP/1.0\r\nHost: %s\r\nRange: %s\r\nUser-Agent: getter\r\n\r\n"
#define HEAD_FORMAT_RANGE "HEAD %s%s HTTP/1.0\r\nHost: %s\r\nRange: %s\r\nUser-Agent: getter\r\n\r\n"
我目前正在使用类似的东西来替换查询字符串的'%s'部分。我觉得这可能会更优美:
char* query_string_formatter(char* page, char* host, int get){
switch(get) {
case 0:
//HEAD
{
char* query = malloc(strlen(host) + strlen(page) + 1 + HEAD_FORMAT_LEN);
if (page[0] == '/') {
sprintf(query,HEAD_FORMAT, "", page, host);
} else {
sprintf(query, HEAD_FORMAT, "/", page, host);
}
return query;
}
default:
//GET
{
char* query = malloc(strlen(host) + strlen(page) + 1 + GET_FORMAT_LEN);
if (page[0] == '/') {
sprintf(query,GET_FORMAT, "", page, host);
} else {
sprintf(query, GET_FORMAT, "/", page, host);
}
return query;
}
}
}
但是id喜欢用更优雅的方式替换它:
...
sprintf(query, format, "",page,host);
格式为GET或HEAD,而不是嵌套多个if语句和重复代码
答案 0 :(得分:2)
为防止代码重复,您可以使用变量在
之前存储格式char* query_string_formatter(char* page, char* host, int get){
char* query = malloc(strlen(host) + strlen(page) + 1 + HEAD_FORMAT_LEN);
char *format;
if (get)
format = GET_FORMAT;
else
format = HEAD_FORMAT;
if (page[0] == '/')
sprintf(query, format, "", page, host);
else
sprintf(query, format, "/", page, host);
return query;
}
或更短,但可读性更差:
char* query_string_formatter(char* page, char* host, int get){
char* query = malloc(strlen(host) + strlen(page) + 1 + HEAD_FORMAT_LEN);
sprintf(query, get ? GET_FORMAT : HEAD_FORMAT, page[0] == '/' ? "" : "/", page, host);
return query;
}
也:请确保HEAD_FORMAT_LEN包含'\ 0'结尾,或在malloc
中添加更多1。
答案 1 :(得分:1)
就个人而言,我会完全消除这些宏,并做类似的事情
const char *format_string[] = {"GET %s%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: getter\r\n\r\n",
"HEAD %s%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: getter\r\n\r\n"};
char* query_string_formatter(const char* page, const char* host, int get)
{
if (get != 0) get = 1;
char* query = malloc(strlen(host) + strlen(page) + 1 + strlen(format[get]);
sprintf(query, format[get], (page[0] == '/' ? "" : "/"), page, host);
return query;
}
(可选)上面的定义format_string
可以放在函数query_string_formatter()
中。将其放在文件范围内的函数之外,可以使该数组由同一源文件中的多个函数使用。
您没有指定,但我假设-在您的代码中-HEAD_FORMAT_LEN
和GET_FORMAT_LEN
可以分别替换为strlen(HEAD_LEN)
和strlen(GET_LEN)
。这或多或少与您的用法一致[事实上,使用strlen()
可能会稍微使用malloc()
来过度分配,但这实际上比分配不足要好-您希望缓冲区长度至少为 复制到它的长度]。
您可能还可以进行更多的合理化处理,因为两个格式字符串之间的唯一区别是开头使用子字符串"GET"
和"HEAD"
。
您还没有显示如何使用宏GET_FORMAT_RANGE
和HEAD_FORMAT_RANGE
的任何示例,但是-如果在代码中以类似的方式使用它们,则可以在类似的方式。