Как убрать пунктуацию со строки в C - PullRequest
4 голосов
/ 03 декабря 2009

Я хочу удалить все знаки препинания из строки и сделать все прописные буквы строчными в C, какие-либо предложения?

Ответы [ 4 ]

11 голосов
/ 03 декабря 2009

Просто набросок алгоритма с использованием функций, предоставляемых ctype.h:

#include <ctype.h>

void remove_punct_and_make_lower_case(char *p)
{
    char *src = p, *dst = p;

    while (*src)
    {
       if (ispunct((unsigned char)*src))
       {
          /* Skip this character */
          src++;
       }
       else if (isupper((unsigned char)*src))
       {
          /* Make it lowercase */
          *dst++ = tolower((unsigned char)*src);
          src++;
       }
       else if (src == dst)
       {
          /* Increment both pointers without copying */
          src++;
          dst++;
       }
       else
       {
          /* Copy character */
          *dst++ = *src++;
       }
    }

    *dst = 0;
}

Применяются стандартные предостережения: полностью не проверены; уточнения и оптимизации оставлены читателю в качестве упражнения.

11 голосов
/ 03 декабря 2009

Зацикливание на символах строки. Всякий раз, когда вы встречаете пунктуацию (ispunct), не копируйте ее в выходную строку. Всякий раз, когда вы встречаете «альфа-символ» (isalpha), используйте tolower, чтобы преобразовать его в строчные.

Все упомянутые функции определены в <ctype.h>

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

5 голосов
/ 03 декабря 2009

Идиоматический способ сделать это в C состоит в том, чтобы иметь два указателя, источник и назначение, и обрабатывать каждый символ индивидуально: например,

#include <ctype.h>

void reformat_string(char *src, char *dst) {
    for (; *src; ++src)
        if (!ispunct((unsigned char) *src))
            *dst++ = tolower((unsigned char) *src);
    *dst = 0;
}

src и dst могут быть одной строкой, так какпункт назначения никогда не будет больше исходного.

Хотя это заманчиво, избегайте вызова tolower(*src++), поскольку tolower может быть реализован как макрос.

Избегайте решений, которые ищут заменяемые символы (используя strchrили аналогичные), они превратят линейный алгоритм в геометрический.

0 голосов
/ 03 декабря 2009

Вот примерный ответ для вас:

void strip_punct(char * str) {
    int i = 0;
    int p = 0;
    int len = strlen(str);
    for (i = 0; i < len; i++) {
        if (! ispunct(str[i]) {
            str[p] = tolower(str[i]);
            p++;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...