[英]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
的末尾。 rs
以nul終止,並返回一個指針。
雖然我很少建議使用scanf
作為輸入((最好在fgets
后面加上sscanf
或strtok
),但出於簡短示例的目的,它可以用於從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.