Функция для удаления запрещенных символов


void removeForbiddenChar(string* s)
{
    string::iterator it;

    for (it = s->begin() ; it < s->end() ; ++it){
        switch(*it){
        case '/':case '\\':case ':':case '?':case '"':case '<':case '>':case '|':
            *it = ' ';
        }
    }
}

Я использовал эту функцию, чтобы удалить строку, которая имеет любой из следующих символов: \, /, :, ?, ", <, >, |. Это имя файла. Эта программа работает нормально. Он просто меняет символ строки в пустую, когда соответствующий символ запретного характера. Однако, мне кажется, на этом использование оператора switch. Я просто эксплуатируют вот синтаксис случай, но это, почему-то ворчит на меня. Мне просто не нравится. У кого-нибудь есть предложение получше лучшей реализации в данном случае?



21573
19
задан 27 января 2011 в 04:01 Источник Поделиться
Комментарии
6 ответов

Объявить строку, содержащую недопустимые символы: "\\/:?"<>|". Все, что вам нужно сделать, это проверить, если char в массив, чтобы использовать встроенную функцию для этого, или написать метод CharInString(типа char* иглы, строка* стог сена) , который просматривает содержимое предоставляется сена, чтобы проверить, если игла находится внутри него.

Ваш цикл должен выглядеть так:

string illegalChars = "\\/:?\"<>|"
for (it = s->begin() ; it < s->end() ; ++it){
bool found = illegalChars.find(*it) != string::npos;
if(found){
*it = ' ';
}
}

Она более ремонтопригодна и читаемым. Вы можете сказать, если вы продублировали персонажа достаточно легко и, поскольку вы можете сделать это с любой целевой строке и в любой строке illegalChars вы только что создали для себя универсальный RemoveIllegalChars(строка* targetString, строки* illegalChars) способ использования в любом месте программы.

Я может быть с помощью этих указателей не так. Мой с++ - Фу слаб... сейчас.

19
ответ дан 27 января 2011 в 04:01 Источник Поделиться

вы всегда можете использовать преобразование

#include <algorithm>
#include <string>
#include <iostream>

const std::string forbiddenChars = "\\/:?\"<>|";
static char ClearForbidden(char toCheck)
{
if(forbiddenChars.find(toCheck) != string::npos)
{
return ' ';
}

return toCheck;
}

int main()
{
std::string str = "EXAMPLE:";
std::transform(str.begin(), str.end(), str.begin(), ClearForbidden);
std::cout << str << std::endl;
return 0;
}

16
ответ дан 27 января 2011 в 04:01 Источник Поделиться

Единственное, что я бы изменил в вашей функции (кроме Джонатана рекомендации, используя строку, чтобы хранить запрещенные символы), является аргумент типа removeForbiddenChar в строки и вместо строки*. Как правило, считается хорошей практикой в C++ использование ссылок на указатели, где это возможно (см., например, эта запись в C++ часто задаваемые вопросы-лайт).

Еще один, мелкие косметические изменения, я рекомендовал бы это переименование функции removeForbiddenChars (во множественном числе), как это более подробно описать, что он делает.

5
ответ дан 27 января 2011 в 04:01 Источник Поделиться

Или, вот еще один способ, вы могли бы сделать это с помощью все вещи из стл:

#include <algorithm>
#include <string>
#include <iostream>

bool isForbidden( char c )
{
static std::string forbiddenChars( "\\/:?\"<>|" );

return std::string::npos != forbiddenChars.find( c );
}

int main()
{
std::string myString( "hell?o" );

std::replace_if( myString.begin(), myString.end(), isForbidden, ' ' );

std::cout << "Now: " << myString << std::endl;
}

5
ответ дан 28 января 2011 в 12:01 Источник Поделиться

Поставляется с полезной функцией в size_t strcspn(константный тип char *строка, константный тип char *разделители) , которые вы можете реализовать это на вершине. Версия ASCII является довольно быстро; он использует битовый вектор для проверки на символы-разделители.

4
ответ дан 27 января 2011 в 09:01 Источник Поделиться

Решение без условного ветвления.
Пространство подкачки для оптимизации времени.

Упрощенный алгоритм:

void removeForbiddenChar(string* s)
{
for (string::iterator it = s->begin() ; it < s->end() ; ++it)
{
// replace element with their counterpart in the map
// This replaces forbidden characters with space.
(*it) = charMap[*it];
}
}

Или C++0х версия:

void removeForbiddenChar(std::string* s)
{
std::transform(s->begin(), s->end(), [](char c) => {return charMap[c];});
}

Просто нужны данные:

char    charMap[] =
// The majority of characters in this array
// map the poistion to the same character code.
// charMap['A'] == 'A'
// For forbidden characters a space is in the position
// charMap['<'] == ' '
// Note: \xxx is an octal escape sequence
"\000\001\002\003\004\005\006\007"
"\010\011\012\013\014\015\016\017"
"\020\021\022\023\024\025\026\027"
"\030\031\032\033\034\035\036\037"
"\040\041 \043\044\045\046\047" // replaced \042(") with space
"\050\051\052\053\054\055\056 " // replaced \057(/) with space
"\060\061\062\063\064\065\066\067"
"\070\071 \073 \075 " // replaced \072(:)\074(<)\076(>)\077(?) with space
"\100\101\102\103\104\105\106\107"
"\110\111\112\113\114\115\116\117"
"\120\121\122\123\124\125\126\127"
"\130\131\132\133 \135\136\137" // replaced \134(\)
"\140\141\142\143\144\145\146\147"
"\150\151\152\153\154\155\156\157"
"\160\161\162\163\164\165\166\167"
"\170\171\172\173\174\175\176\177"
"\200\201\202\203\204\205\206\207"
"\210\211\212\213\214\215\216\217"
"\220\221\222\223\224\225\226\227"
"\230\231\232\233\234\235\236\237"
"\240\241\242\243\244\245\246\247"
"\250\251\252\253\254\255\256\257"
"\260\261\262\263\264\265\266\267"
"\270\271\272\273\274\275\276\277"
"\300\301\302\303\304\305\306\307"
"\310\311\312\313\314\315\316\317"
"\320\321\322\323\324\325\326\327"
"\330\331\332\333\334\335\336\337"
"\340\341\342\343\344\345\346\347"
"\350\351\352\353\354\355\356\357"
"\360\361\362\363\364\365\366\367"
"\370\371\372\373\374\375\376\377";

4
ответ дан 28 января 2011 в 02:01 Источник Поделиться