繁体   English   中英

在C中绕元音旋转单词

[英]Rotate words around vowels in C

我正在尝试编写一个程序,该程序读取stdin流以查找单词(连续的字母字符),然后将每个单词向左旋转到第一个元音(例如,“ friend”旋转为“ iendfr”),并以此顺序代替原来的词。 所有其他字符均不变地写入stdout。

到目前为止,我设法扭转了这些字母,但无法做更多的事情。 有什么建议么?

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_STK_SIZE 256

char stk[MAX_STK_SIZE];
int tos = 0; // next available place to put char

void push(int c) {
    if (tos >= MAX_STK_SIZE) return;
    stk[tos++] = c;
}

void putStk() {
    while (tos >= 0) {
        putchar(stk[--tos]);
    }
}

int main (int charc, char * argv[]) {
    int c;
    do {
        c = getchar();
        if (isalpha(c) && (c == 'a' || c == 'A' || c == 'e' || c ==         'E' || c == 'i' || c == 'o' || c == 'O' || c == 'u' || c == 'U')) {
            push(c);
        } else if (isalpha(c)) {
            push(c);
        } else {
            putStk();
            putchar(c);
        }
    } while (c != EOF);
}

-灵魂

我不会为您编写整个程序,但是此示例显示了如何从第一个元音(如果有)旋转一个单词。 函数strcspn返回与所传递的集合中的任何字符匹配的第一个字符的索引,如果找不到匹配项,则返回字符串的长度。

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

void vowelword(const char *word)
{
    size_t len = strlen(word);
    size_t index = strcspn(word, "aeiou");
    size_t i;
    for(i = 0; i < len; i++) {
        printf("%c", word[(index + i) % len]);
    }
    printf("\n");
}

int main(void)
{
    vowelword("friend");
    vowelword("vwxyz");
    vowelword("aeiou");
    return 0;
}

程序输出:

iendfr
vwxyz
aeiou

您可以采用多种方法来解决问题。 您可以使用堆栈,但这只是增加了对其他堆栈操作的处理。 您可以使用数学上的重新索引编制,也可以使用复制和填充解决方案,从第一个元音复制到新字符串,然后将初始字符添加到字符串的末尾。

虽然您一次可以读取/写入一个字符,但最好通过在缓冲区中创建旋转的字符串以允许在代码中使用该字符串来更好地为您服务。 无论使用哪种方法,都需要验证所有字符串操作,以防止在输入和/或旋转的字符串末尾进行读/写操作。 复制/填充方法以旋转到输入中的第一个元音的示例可能类似于以下内容:

/* rotate 's' from first vowel with results to 'rs'. 
 * if 's' contains a vowel, 'rs' contains the rotated string, 
 * otherwise, 'rs' contais 's'. a pointer to 'rs' is returned
 * on success, NULL otherwise and 'rs' is an empty-string.
 */
char *rot2vowel (char *rs, const char *s, size_t max)
{
    if (!rs || !s || !max)  /* validate params */
        return NULL;

    char *p = strpbrk (s, "aeiou");
    size_t i, idx, len = strlen (s);

    if (len > max - 1) {    /* validate length */
        fprintf (stderr, "error: insuffieient storage (len > max - 1).\n");
        return NULL;
    }

    if (!p) {   /* if no vowel, copy s to rs, return rs */
        strcpy (rs, s);
        return rs;
    }

    idx = p - s;        /* set index offset    */
    strcpy (rs, p);     /* copy from 1st vowel */

    for (i = 0; i < idx; i++)   /* rotate beginning to end */
        rs[i+len-idx] = s[i];

    rs[len] = 0;        /* nul-terminate */

    return rs;
}

上面, strpbrk用于返回指向字符串's'元音的第一个出现的指针。 该函数将指向足够大小的字符串的指针作为参数,以容纳旋转后的字符串'rs' ,输入字符串's''rs'的已分配大小'max' 验证参数并检查s是否具有strpbrk的元音,该元音返回指向s第一个元音的指针(如果存在),否则返回NULL 对照max长度检查长度,以确保有足够的存储空间。

如果不存在元音,则将s复制到rs并返回指向rs的指针,否则使用指针差将第一个元音的偏移量索引设置为从第一个元音到末尾的字符串段rs ,然后使用循环将前面的字符复制到rs的末尾。 rsnul终止,并返回一个指针。

虽然我很少建议使用scanf作为输入((最好在fgets后面加上sscanfstrtok ),但出于简短示例的目的,它可以用于从stdin读取单个字符串。 注意:对大/小写元音的响应留给您。 一个简短的示例将最大单词大小设置为32个字符(31个字符+零终止字符)将适用于未删节词典中的所有已知单词(最长单词为28个字符):

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

enum { BUFSZ = 32 };

char *rot2vowel (char *rs, const char *s, size_t max);

int main (void)
{
    char str[BUFSZ] = {0};
    char rstr[BUFSZ] = {0};

    while (scanf ("%s", str) == 1)
        printf (" %-8s => %s\n", str, rot2vowel (rstr, str, sizeof rstr));

    return 0;
}

使用/输出示例

(无耻地从WeatherVane借用示例字符串:)

$ echo "friend vwxyz aeiou" | ./bin/str_rot2vowel
 friend   => iendfr
 vwxyz    => vwxyz
 aeiou    => aeiou

仔细看一下,如果您有任何问题,请告诉我。 注意:您可以在printf语句之前调用rot2vowel函数,并使用rstr打印结果,但是由于该函数返回指向字符串的指针,因此可以直接在printf语句中使用它。 如何使用取决于您自己。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM