2015-02-24 6 views
0

Мне нужна функция, которая даст мне экранированный специальный символ из символа буквы. Это применимо только тогда, когда это имеет смысл: 't', 'n', 'r', 'b', 'f', 'v'.Как преобразовать символ буквы в соответствующий экранированный специальный символ

Прямо сейчас, вот моя реализация:

typedef struct SpecialCharacter 
{ 
    SpecialCharacter(char letter, char special) 
    { 
     m_letter = letter; 
     m_special = special; 
    } 

    char m_letter; 
    char m_special; 
} SpecialCharacter; 

typedef std::vector<SpecialCharacter> SpecialCharacters; 

static const SpecialCharacters& GetSpecialCharacters() 
{ 
    static SpecialCharacters characters; 
    if (characters.empty()) 
    { 
     characters.push_back(SpecialCharacter('b', '\b')); 
     characters.push_back(SpecialCharacter('f', '\f')); 
     characters.push_back(SpecialCharacter('n', '\n')); 
     characters.push_back(SpecialCharacter('r', '\r')); 
     characters.push_back(SpecialCharacter('t', '\t')); 
     characters.push_back(SpecialCharacter('v', '\v')); 
    } 
    return characters; 
} 

static bool getEscaped(char letter, char& escaped) 
{ 
    for (SpecialCharacters::const_iterator iter = GetSpecialCharacters().begin(); 
      iter != GetSpecialCharacters().end(); 
      ++iter) 
    { 
     if (letter == iter->m_letter) 
     { 
      escaped = iter->m_special; 
      return true; 
     } 
    } 
    return false; 
} 

мне не нравится, как я добавляю элементы вектора символов:

characters.push_back(SpecialCharacter('b', '\b')); 

Будет ли способ сделать :

characters.push_back(SpecialCharacter('b')); 

, а затем что-то вроде:

SpecialCharacter(char letter) 
{ 
    m_letter = letter; 
    m_special = '\' + letter; // does not work, of course! 
} 

Я хотел бы способ объединить «\» и «п» в «\ п», или получить «\ п» от «п» любым другим способом ...

Edit: случай что я был изначально, прежде чем я переместил код в вектор struct (потому что мне нужна функция, чтобы обойти вокруг). Так что это не будет хорошим решением моей проблемы. Я хотел бы преобразовать «n» в «\ n» без какой-либо «таблицы поиска»

+0

просто любопытно, в чем же цель? – sanjayk79

+0

Необходимо вручную обрабатывать, защищать и преобразовывать эти символы для экспорта скриптов, которые будут использоваться внешним парсером. В одном случае пользователь вводит текст «bbb \ n» в графическом интерфейсе, и мне нужно заменить «bbb \ n» на «bbb \\ n», чтобы «\ n» отображался в экспортированном файле, а не в реальной карете вернуть. Но есть и другие условия, когда мне нужно отображать 'n' в '\ n' или в моем коде. – jpo38

+0

вы можете создать простой escaped_char [128] (для печатаемых символов), например. escaped_char ['f'] = '\ f' и escaped_char ['a'] = 'a'. Даже посмотрев на экранированную фигуру, я не знаю, как это поможет. Посмотрите на http://stackoverflow.com/questions/2417588/escaping-a-c-string – sanjayk79

ответ

3

n и \n - совершенно разные символы. Они никак не связаны друг с другом. \n - всего лишь мнемоника. Формулы нет.

+0

Даже с макросом? – jpo38

+1

Макросы не магически изобретают отношения между двумя вещами. Вы не можете просто выбросить слово «макрос» как ответ на какое-то утверждение, как если бы оно означало что-то вне контекста: P –

+0

Я думал о синтаксисе mcro, который бы волшебным образом слил ', \, n и' into ' \ n'' ... поскольку они способны объединять строки вместе ... – jpo38

-2

Возможно, это то, что вы ищете?

https://stackoverflow.com/a/5612287/4405589

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

Edit: добавлен пример:

#include <iostream> 

char GetSpecialCharacter(char c){ 
    switch(c){ 
     case 'n': 
      return '\n'; 
     case 'r': 
      return '\r'; 
     case 't': 
      return '\t'; 
     // More espace character checks here... 
     default: 
      return '\0'; 
    } 
} 

int main(void){ 
    std::cout << "This is a " << GetSpecialCharacter('n') << "test."; 
    return 0; 
} 
+0

Это эквивалентно тому, что у меня есть, но с футляром, а не статическим вектором ... – jpo38

+0

Ссылка только ответ = плохо –

0

Ваша реализация выглядит хорошо, оптимизация по модулю с помощью switch, constexpr и/или макросы.

Нет связи между 'x' и '\x', без фиксированного ASCII-смещения между ними для всех x.

Итак, вы не можете сделать лучше, чем таблица поиска.

0

Нет специального способа конвертировать 'n' в '\n', поскольку они являются полностью несвязанными значениями; в отображаемом вами сопоставлении нет шаблона. Вы выполняете простое целочисленное сопоставление (в случае 'n' - '\n', сопоставление 0x6E - 0x0A). Я бы рекомендовал более простую реализацию, чем вы делаете, особенно для столь немногих отображений:

static bool getEscaped(char letter, char& escaped) 
{ 
    switch(letter) 
    { 
    case 'b': 
     escaped = '\b'; 
     return true; 
    case 'f': 
     escaped = '\f'; 
     return true; 
    case 'n': 
     escaped = '\n'; 
     return true; 
    case 'r': 
     escaped = '\r'; 
     return true; 
    case 't': 
     escaped = '\t'; 
     return true; 
    case 'v': 
     escaped = '\v'; 
     return true; 
    } 
    escaped = letter; 
    return false; 
} 

Если вы абсолютно мертвой набор на никогда не имея на самом деле определяет отображение в явном виде, настаивая на том, что вы использовать отношения в C++ символа для ваших целей, тогда вы можете написать свой собственный препроцессор, чтобы сгенерировать оператор switch, который я поставил выше. Я не рекомендую это для обработки только 6 случаев.

В сущности, вы делаете небольшое отображение из 6 целых чисел в 6 других несвязанных целых чисел. Просто используйте switch.

+0

Это эквивалентно тому, что у меня есть, но с футляром, а не статическим вектором ... – jpo38

+0

Да, я ответил на ваш вопрос и обеспечил более простую альтернативу. – tenfour

+0

@ jpo38 Вы, похоже, зациклились на получении конкретного ответа. Почему вы задали такой открытый вопрос, если вы только согласны принять ответ, который хотите услышать? – tenfour

Смежные вопросы