簡體   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