[英]Replacing spaces with %20 in C
I am writing a fastcgi application for my site in C. Don't ask why, leave all that part. 我正在为我的网站写一个fastcgi应用程序。不要问为什么,留下所有这一部分。
Just help me with this problem- I want to replace spaces in the query string with %20. 只是帮我解决这个问题 - 我想用%20替换查询字符串中的空格。 Here's the code I'm using, but I don't see 20 in the output, only %.
这是我正在使用的代码,但我没有在输出中看到20,只有%。 Where's the problem?
哪里有问题?
Code: 码:
unsigned int i = 0;
/*
* Replace spaces with its hex %20
* It will be converted back to space in the actual processing
* They make the application segfault in strtok_r()
*/
char *qstr = NULL;
for(i = 0; i <= strlen(qry); i++) {
void *_tmp;
if(qry[i] == ' ') {
_tmp = realloc(qstr, (i + 2) * sizeof(char));
if(!_tmp) error("realloc() failed while allocting string memory (space)\n");
qstr = (char *) _tmp;
qstr[i] = '%'; qstr[i + 1] = '2'; qstr[i + 2] = '0';
} else {
_tmp = realloc(qstr, (i + 1) * sizeof(char));
if(!_tmp) error("realloc() failed while allocating string memory (not space)\n");
qstr = (char *) _tmp;
qstr[i] = qry[i];
}
}
In the code, qry is char *, comes as a actual parameter to the function. 在代码中,qry是char *,作为函数的实际参数。 I tried with i + 3, 4, 5 in realloc() in the space replacer block, no success.
我尝试在空间替换块中的realloc()中使用i + 3,4,5,但没有成功。
String-handling in C can be tricky. C中的字符串处理可能很棘手。 I'd suggest going through the string first, counting the spaces, and then allocating a new string of the appropriate size (original string size + (number of spaces * 2)).
我建议首先查看字符串,计算空格,然后分配一个适当大小的新字符串(原始字符串大小+(空格数* 2))。 Then, loop through the original string, maintaining a pointer (or index) to the position in both the new string and the original one.
然后,循环遍历原始字符串,将指针(或索引)保持在新字符串和原始字符串中的位置。 (Why two pointers? Because every time you encounter a space, the pointer into the new string will get two characters ahead of the pointer into the old one.)
(为什么有两个指针?因为每次遇到空格时,指向新字符串的指针都会在指针前面有两个字符进入旧字符串。)
Here's some code that should do the trick: 这里有一些代码可以解决这个问题:
int new_string_length = 0;
for (char *c = qry; *c != '\0'; c++) {
if (*c == ' ') new_string_length += 2;
new_string_length++;
}
char *qstr = malloc((new_string_length + 1) * sizeof qstr[0]);
char *c1, *c2;
for (c1 = qry, c2 = qstr; *c1 != '\0'; c1++) {
if (*c1 == ' ') {
c2[0] = '%';
c2[1] = '2';
c2[2] = '0';
c2 += 3;
}else{
*c2 = *c1;
c2++;
}
}
*c2 = '\0';
qstr[i] = '%'; qstr[i + 1] = '2'; qstr[i + 2] = '0';
That line writes three characters to your output buffer, so the next character you write needs to be written at qstr[i+3]. 该行将三个字符写入输出缓冲区,因此您编写的下一个字符需要写入qstr [i + 3]。 However, you only step i by 1, so the next character is written to qstr[i+1], overwriting the '2'.
但是,您只需逐步减1,因此下一个字符将写入qstr [i + 1],覆盖'2'。
You will need to keep separate indexes for stepping through qry
& qstr
. 您需要保留单独的索引来逐步执行
qry
& qstr
。
I agree with David. 我同意大卫的观点。
It is advisable to do it in two-steps: in the first loop you just count the spaces: 建议分两步执行:在第一个循环中,您只需计算空格:
int spaceCounter=0;
const int sourceLen = strlen(qry);
for(int i = 0; i < sourceLen; ++i)
if ( qry[i] == ' ')
++spaceCounter;
char* newString = (char*)malloc(sourceLen + 3*spaceCounter*sizeof(char) + 1)
//check for null!
for(int i = 0; i < sourceLen; ++i)
if ( qry[i] == ' ')
{
*newString++ = '%';
*newString++ = '2';
*newString++ = '0';
}
else
*newString++ = qry[i];
*newString = '\0';
Warning: code not tested. 警告:代码未经过测试。
You are assigning using the same counter I you will need to have 2 counters since the strings have different lengths 您使用相同的计数器分配我需要有2个计数器,因为字符串具有不同的长度
your else case assigns qstr[i] = qry[i]; 你的其他案例指定qstr [i] = qry [i]; after you have written the %20 you are at least off by 2 on the result string.
写完%20后,你在结果字符串上至少减去2。
This is known as url encode. 这称为url编码。 You can refer to this page to see some similar implementation: http://www.geekhideout.com/urlcode.shtml
您可以参考此页面查看类似的实现: http : //www.geekhideout.com/urlcode.shtml
char* toHexSpace(const char *s)
{
char *b=strcpy(malloc(3*strlen(s)+1),s),*p;
while( p=strchr(b,' ') )
{
memmove(p+3,p+1,strlen(p));
strncpy(p,"%20",3);
}
return b;
}
needs "free" in calling context. 在呼叫上下文中需要“免费”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.