2015-11-29 3 views
0

Я хочу заменить все специальные символы в строке своими экранированными эквивалентами (\n \t \\ \"). Моя идея - использовать читателя и писателя, а затем поставить \\ перед любым специальным символом. Я использую динамический указатель массива/char.Экранирование символов в C

Поскольку я не настолько уверен в понимании указателей, я по-прежнему склонен чаще использовать массивы, чем указатели.

Как обычно, с C я получаю в основном (только) мусор в качестве выхода. Откуда мне это неопределенное поведение? Мой код:

char *escapeChars(const char *src) 
{ 
    int i, counter = 0, j = 0; 
    size_t size = strlen(src) + 1; 
    char pr[size], *pw; 
    pr[0] = '\0'; 

    strcat(pr, src); /*to get the constness away*/ 
    pw = pr; 
    for(i = 0; i < ((int) sizeof(pr)); i++){ 
      if(pr[i] == '\n' || pr[i] == '\t' || pr[i] == '\\' || pr[i] == '\"'){ 
        counter++; 
      } 
    } 
    pw = malloc(sizeof(pr) + (size_t) counter); 

    for(i = 0; i <((int) sizeof(pr)); i++){ 
      if(pr[i] != '\n' || pr[i] != '\t' || pr[i] != '\\' || pr[i] != '\"'){ 
        pw[i+j] = pr[i]; 
      } else { 
        pw[i+j] = '\\'; 
        pw[i+j+1] = pr[i]; 
        j++; 
      } 
    } 
    pw[i + j] = '\0'; 
    return pw; 
} 

В качестве результата я получаю совершенно неправильный материал. И я считаю, что это терпит неудачу, когда встречается с первым специальным символом.

Original string: Some 
string with "special characters". And \. 
Result: Some 
str 

Если что-то даже немного неясно, сообщите мне об этом.

+2

С одной стороны, выражение if ... not equals on line 18 будет проблематичным. Он всегда будет возвращать true. –

+0

Да, '||'? – user8

+0

Не могли бы вы показать, как именно вызывается 'escapeChars'? – kaylum

ответ

2

Вам нужно особый случай замены '\n' на '\\' + 'n' и т.д.

Там нет необходимости, чтобы сделать локальную копию src для поиска специальных символов. Вы можете упростить код таким образом:

char *escapeChars(const char *src) { 
    int i, j; 
    char *pw; 

    for (i = j = 0; src[i] != '\0'; i++) { 
     if (src[i] == '\n' || src[i] == '\t' || 
      src[i] == '\\' || src[i] == '\"') { 
      j++; 
     } 
    } 
    pw = malloc(i + j + 1); 

    for (i = j = 0; src[i] != '\0'; i++) { 
     switch (src[i]) { 
     case '\n': pw[i+j] = '\\'; pw[i+j+1] = 'n'; j++; break; 
     case '\t': pw[i+j] = '\\'; pw[i+j+1] = 't'; j++; break; 
     case '\\': pw[i+j] = '\\'; pw[i+j+1] = '\\'; j++; break; 
     case '\"': pw[i+j] = '\\'; pw[i+j+1] = '\"'; j++; break; 
     default: pw[i+j] = src[i]; break; 
     } 
    } 
    pw[i+j] = '\0'; 
    return pw; 
} 

Обратите внимание, что вы должны также избежать некоторых других персонажей: '\r', и недопущения печати или не портативные символы в диапазоне от 1 до 31 и 127 до 255 ASCII. Выйти из них, как восьмеричные последовательности, больше работают, но управляемы на вашем уровне мастерства.

+1

, но 'pr' объявлен как массив символов, поэтому' sizeof (pr) 'будет числом элементов + 1. Или? – user8

+0

Это правильно. Я исправил ответ. Неверно использовать 'sizeof (pr)', тем более, что этот массив имеет динамический размер (VLA) и на самом деле не нужен для этой функции. – chqrlie

+0

- это то же самое, что и src? – user8