Замена пробелов на% 20 в C - PullRequest
       1

Замена пробелов на% 20 в C

4 голосов
/ 06 августа 2010

Я пишу приложение fastcgi для своего сайта в C. Не спрашивай почему, оставь всю эту часть.

Просто помогите мне с этой проблемой - я хочу заменить пробелы в строке запроса на% 20. Вот код, который я использую, но я не вижу 20 в выводе, только%. Где проблема?

Код:

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];
  }
}

В коде qry - это char *, это фактический параметр функции. Я попытался с i + 3, 4, 5 в realloc () в блоке заменителя пространства, безуспешно.

Ответы [ 6 ]

16 голосов
/ 06 августа 2010

Обработка строк в C может быть сложной.Я бы предложил сначала просмотреть строку, сосчитав пробелы, а затем выделить новую строку соответствующего размера (исходный размер строки + (количество пробелов * 2)).Затем выполните цикл по исходной строке, сохраняя указатель (или индекс) на позицию как в новой строке, так и в исходной.(Почему два указателя? Потому что каждый раз, когда вы сталкиваетесь с пробелом, указатель на новую строку будет на два символа опережать указатель на старую.)

Вот некоторый код, который должен помочь:

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';
6 голосов
/ 06 августа 2010
qstr[i] = '%'; qstr[i + 1] = '2'; qstr[i + 2] = '0'; 

Эта строка записывает три символа в ваш выходной буфер, поэтому следующий записанный вами символ должен быть записан в qstr [i + 3].Однако вы только шаг i на 1, поэтому следующий символ записывается в qstr [i + 1], перезаписывая '2'.

Вам нужно будет хранить отдельные индексы для перехода по qry & qstr.

2 голосов
/ 06 августа 2010

Я согласен с Дэвидом.

Желательно сделать это в два этапа: в первом цикле просто посчитать пробелы:

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';

Предупреждение: код не проверен.

1 голос
/ 06 августа 2010

Вы назначаете с использованием одного и того же счетчика. Вам понадобится 2 счетчика, так как строки имеют разную длину

В другом случае вы назначаете qstr [i] = qry [i];после того как вы написали% 20, вы как минимум на 2 в строке результата.

0 голосов
/ 06 августа 2010
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; 
}

нуждается в "свободе" в контексте вызова.

0 голосов
/ 06 августа 2010

Это называется кодированием URL.Вы можете обратиться к этой странице, чтобы увидеть похожую реализацию: http://www.geekhideout.com/urlcode.shtml

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...