Как удалить гласные в строке с помощью указателей - PullRequest
1 голос
/ 16 октября 2019

Я хочу удалить гласные из строки и распечатать остальные. Но мое , если условие не работает должным образом.

    #include <stdio.h>

    void filter (char *p, char *q)
    {
      while (*p != '\0')
        {
          if (*p != 'a' || *p != 'e' || *p != 'i' || *p != 'o' || *p != 'u')
        {
          *q = *p;
          q++;
        }
          p++;
        }
      *q = '\0';
    }

    int main ()
    {
      char str1[10] = "hello";
      char str2[10];
      char *p, *q;
      p = &str1[0];
      q = &str2[0];
      filter (p, q);
      printf ("%s", str2);
      return 0;
    }

Я ожидаю, что на выходе будет hll , но на выходе было привет ,Хотелось бы узнать причину ошибки и способ ее устранения.

Ответы [ 4 ]

6 голосов
/ 16 октября 2019

Это здесь:

if (*p != 'a' || *p != 'e' || *p != 'i' || *p != 'o' || *p != 'u')

Должно быть:

if (*p != 'a' && *p != 'e' && *p != 'i' && *p != 'o' && *p != 'u')

В примечании вы можете пропустить часть char *p, *q;. Просто сделай это так:

int main()
{
    char str1[10] = "hello";
    char str2[10];
    filter(str1, str2);
    printf("%s", str2);
    return 0;
}
4 голосов
/ 16 октября 2019

Проверьте, если условие. Это всегда правда. Используйте && вместо ||. В вашем примере 'e' не равно 'a', и поэтому условие становится истинным, и в результирующую строку добавляется символ. Попробуйте это:

if (*p != 'a' && *p != 'e' &&*p != 'i' && *p != 'o' && *p != 'u')

2 голосов
/ 16 октября 2019

Условие

if (*p != 'a' || *p != 'e' || *p != 'i' || *p != 'o' || *p != 'u')

неверно. Например, когда *p равно 'e', то есть когда * p является гласным, выражение *p != 'a' дает значение true, и это результат полного условия.

Вы должны написать оператор ifкак

if (*p != 'a' && *p != 'e' && *p != 'i' && *p != 'o' && *p != 'u')

или как

if ( ! ( *p == 'a' || *p == 'e' || *p = 'i' || *p != 'o' || *p != 'u') )

Кроме того, следуя соглашению для стандартных строковых функций C, функция должна возвращать указатель на строку результата. И первый параметр должен иметь квалификатор const, поскольку указанная строка не изменяется в функции.

Вместо использования длинного выражения в условии if можно использовать стандартную функцию C strchr, чтобы проверить, является лиУказанный символ является гласным или нет.

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

#include <stdio.h>
#include <string.h>

char * filter( const char *p, char *q )
{
    const char *vowels = "aeiou";
    char *result = q;

    do
    {
        if ( *p == '\0' || strchr( vowels, *p ) == NULL ) *q++ = *p;
    } while ( *p++ );

    return result;
}

int main(void) 
{
    char *str1 = "hello";
    char str2[10];

    puts( filter( str1, str2 ) );

    return 0;
}

Ее вывод

hll

ИВы можете изменить функцию так, чтобы она пропускала гласные в верхнем регистре.

Например

#include <stdio.h>
#include <string.h>
#include <ctype.h>

char * filter( const char *p, char *q )
{
    const char *vowels = "aeiou";
    char *result = q;

    do
    {
        if ( *p == '\0' || strchr( vowels, tolower( ( unsigned char )*p ) ) == NULL ) 
        {
            *q++ = *p;
        }           
    } while ( *p++ );

    return result;
}

int main(void) 
{
    char *str1 = "HELLO";
    char str2[10];

    puts( filter( str1, str2 ) );

    return 0;
}

Вывод программы:

HLL
0 голосов
/ 16 октября 2019

Все остальные ответы четко относятся к логической ошибке.
Этот просто предлагает мысль о читабельности или стиле. (и небольшое улучшение логики.)

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

    void filter (char *p, char *q)
    {
      while (*p != '\0')
        {
          if (NOT_VOWEL(*p))
        {
          *q = *p;
          q++;
        }
          p++;
        }
      *q = '\0';
    }

С помощью C Macro :

Где макрос определяется как:

//either in a header file, or somewhere at 
//the top of of the .c file where it is used.
#define NOT_VOWEL(x) (x != 'a' && x != 'e' && x != 'i' && x != 'o' && tolower(x) != 'u')  

Или с небольшим улучшением:

#define NOT_VOWEL(x) (tolower(x) != 'a' && tolower(x) != 'e' && tolower(x) != 'i' && tolower(x) != 'o' && tolower(x) != 'u')  

(Обратите внимание, что этот вариант макроса включает tolower () функция, чтобы исключить прописные гласные.)

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