【问题标题】:How can I move all vowels from a string to a different array如何将所有元音从字符串移动到不同的数组
【发布时间】:2019-11-01 09:32:26
【问题描述】:

我正在尝试用 C 语言编写一个带有 2 个参数(char *string_1,char *string_2)的函数,它将所有元音从 string_1 移动到 string_2。我写了一个函数来做到这一点,但输出不是我所期望的。 string_2 的内容似乎很随机,有时还包含非元音。

我编写了一个 while 循环来遍历 string_1,并使用 if 语句检查元音。使用指针,我尝试将 string_2 + i 的内容设置为元音。然后,我将 string_1 中元音所在的位置设为 ' '。我尝试了几种不同的算法,并对其进行了跟踪,但我不确定问题出在哪里。另外,我不允许使用字符串库。任何帮助是极大的赞赏。

#include<stdio.h>
#define MAX_STR_LEN 2048

void moveVowels(char *string_1, char *string_2)
{

 int i;
 i=0;
 while (*(string_1 + i) != '\0')
 {
    if (*(string_1 + i) == 'a' || *(string_1 + i) == 'A' || *(string_1 + 
    i) == 'e' || *(string_1 + i) == 'E' || *(string_1 + i) == 'i' ||
    *(string_1 + i) == 'I' || *(string_1 + i) == 'o' || *(string_1 + i) == 
    'O' || *(string_1 + i) == 'u' || *(string_1 + i) == 'U')
    {
    *(string_2 + i) = *(string_1 + i);
    *(string_1 + i) = ' ';
    }
    i++;
 }
}


int main()
{
 char stringy[MAX_STR_LEN]="but they also had a secret, and their greatest 
 fear";
 char vowels[MAX_STR_LEN];
 printf("%s\n",stringy);
 moveVowels(&stringy[0],&vowels[0]);
 printf("%s\n", stringy);
 printf("%s\n", vowels);

 return 0;

}

预期输出:

but they also had a secret, and their greatest fear
b t th y  ls  h d   s cr t,  nd th  r gr  t st f  r
ueaoaaeeaeieaeea

实际输出:

but they also had a secret, and their greatest fear
b t th y  ls  h d   s cr t,  nd th  r gr  t st f  r
\u]

【问题讨论】:

  • 请不要写*(pointer+index)。它有一个可读的简写:pointer[index]
  • 你应该这样做 char vowels[MAX_STR_LEN] = {0}; 否则你不会有一个空终止符
  • 还要记住,数组自然会衰减为指向其第一个元素的指针。所以表达式stringy 完全等于&amp;stringy[0]。您使用两者,以及上面提到的显式指针算法。请坚持one一致的风格。这将使您的代码更易于阅读。
  • 请注意,您需要跟踪两个不同的索引,而不是索引到具有相同索引的两个数组中。
  • 元音数组开头的被初始化为垃圾。比如说,为了论证元音的第一个元素是空终止字符,那么,你什么都不写,因为 stringy 中的第一个字符不是元音。对于 printf,您的 char* 为空。其次,如果您不想在元音中使用空格,则需要另一个索引,而不是 i。三个建议:1. 将数组初始化为零,正如@Gillespie 指出的那样 2. 为元音设置另一个索引,该索引仅针对元音递增,这样您就可以避免空格。

标签: c algorithm pointers c-strings


【解决方案1】:

要跟踪目标字符串中的偏移量,您可以引入一个新变量 - 或者只是增加指针本身。

选项 1

在这种情况下,您需要一个单独的变量来跟踪目标字符串中的偏移量。在您的 moveVowels() 函数中,添加一个新变量

int j = 0;

改变

*(string_2 + i) = *(string_1 + i);

*(string_2 + j++) = *(string_1 + i);

moveVowels()函数的末尾,给目标字符串添加一个NULL终止符:

*(string_2 + j) = '\0';

选项 2

在这种情况下,您只需在每次添加新元音时增加指针:

*(string_2++) = *(string_1 + i);

同样,不要忘记空终止符:

*string_2 = '\0';

【讨论】:

    【解决方案2】:

    我们,初学者,应该互相帮助。:)

    你来了。

    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX_STR_LEN 2048
    
    char * moveVowels( char *s1, const char *s2 )
    {
        const char *vowels = "aeiou";
    
        size_t n = strlen( s2 );
    
        for ( char *p = s1; *s2 != '\0'; ++s2 )
        {
            if ( strchr( vowels, tolower( ( unsigned char )*s2 ) ) != NULL )
            {
                s1[n++] = *s2;
                *p++ = ' ';
            }
            else
            {
                *p++ = *s2;
            }
        }
    
        s1[n] = '\0';
    
        return s1;
    }
    
    int main(void) 
    {
        char s1[MAX_STR_LEN] =
        {
            "but they also had a secret, and their greatest fear"
        };
    
        char s2[MAX_STR_LEN];   
    
        puts( s1 );
        puts( moveVowels( s2, s1 ) );
    
        return 0;
    }
    

    程序输出是

    but they also had a secret, and their greatest fear
    b t th y  ls  h d   s cr t,  nd th  r gr  t st f  rueaoaaeeaeieaeea
    

    考虑到目标字符数组必须有足够的空间来容纳源字符串尾部的元音。

    如果你想在源字符串和元音之间插入换行符,那么函数可以如下所示。

    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX_STR_LEN 2048
    
    char * moveVowels( char *s1, const char *s2 )
    {
        const char *vowels = "aeiou";
    
        size_t n = strlen( s2 );
    
        s1[n++] = '\n';
    
        for ( char *p = s1; *s2 != '\0'; ++s2 )
        {
            if ( strchr( vowels, tolower( ( unsigned char )*s2 ) ) != NULL )
            {
                s1[n++] = *s2;
                *p++ = ' ';
            }
            else
            {
                *p++ = *s2;
            }
        }
    
        s1[n] = '\0';
    
        return s1;
    }
    
    int main(void) 
    {
        char s1[MAX_STR_LEN] =
        {
            "but they also had a secret, and their greatest fear"
        };
    
        char s2[MAX_STR_LEN];   
    
        puts( s1 );
        puts( moveVowels( s2, s1 ) );
    
        return 0;
    }
    

    本例中的程序输出为

    but they also had a secret, and their greatest fear
    b t th y  ls  h d   s cr t,  nd th  r gr  t st f  r
    ueaoaaeeaeieaeea
    

    如果您不允许使用标准 C 字符串函数,那么您可以将它们的调用替换为循环。

    例如声明

    size_t n = strlen( s2 );
    

    可以代替这段代码sn-p

    size_t n = 0;
    
    while ( s2[n] ) ++n;
    

    所以您需要自己用函数strchr 替换循环。

    【讨论】:

    • 根据 OP,不允许使用字符串函数。 IE。没有strlen() 也没有strchr()
    • @user3629249 他的任务是用函数代替某种循环。
    【解决方案3】:

    以下建议的代码:

    1. 干净编译
    2. 不使用任何字符串函数
    3. 执行所需的功能
    4. 避免使用printf(),因为它非常占用 CPU
    5. 避免使用如下表达式:*(string_1 + i)
    6. 使用暴露toupper()ctype.h头文件

    现在,建议的代码:

    #include <stdio.h>
    #include <ctype.h>
    
    #define MAX_STR_LEN 2048
    
    void moveVowels(char *str, char *extractedVowels)
    {
        for( size_t j = 0, i = 0; string_1[i]; i++ )
        {
            int temp = toupper( str[i] );
            if (   temp == 'A' 
                || temp == 'E' 
                || temp == 'I' 
                || temp == 'O' 
                || temp == 'U')
            {
                extractedVowels[j] = str[i];
                j++;
                str[i] = ' ';
            }
        }
    }
    
    
    int main( void )
    {
        char stringy[MAX_STR_LEN]="but they also had a secret, and their greatest fear";
        char vowels[MAX_STR_LEN] = {'\0'};
    
        puts( stringy );
    
        moveVowels(&stringy[0],&vowels[0]);
    
        puts( stringy );
        puts( vowels );
    
        return 0;
    }
    

    运行建议的代码会导致:

    but they also had a secret, and their greatest fear
    b t th y  ls  h d   s cr t,  nd th  r gr  t st f  r
    ueaoaaeeaeieaeea
    

    但是,当尾随的 'y' 也是元音时,OPs 代码(和建议的代码)无法处理。

    【讨论】:

      猜你喜欢
      • 2021-06-20
      • 2019-09-28
      • 1970-01-01
      • 2016-11-12
      • 2020-11-08
      • 2018-12-17
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      相关资源
      最近更新 更多