我正在尝试编写一个程序来读取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);
}
-Soul
答案 0 :(得分:2)
我不打算为你编写整个程序,但这个例子展示了如何从第一个元音(如果有的话)旋转一个单词。函数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
答案 1 :(得分:1)
您可以通过多种方式解决问题。您可以使用堆栈,但这只会增加处理额外的堆栈操作。您可以使用数学重建索引,也可以使用复制和填充解决方案,从第一个元音复制到新字符串,然后只需将初始字符添加到字符串的末尾。
虽然您可以一次读/写一个字符,但通过在缓冲区中创建旋转字符串以允许在代码中使用字符串,可能会更好。无论使用哪种方法,都需要验证所有字符串操作,以防止在输入结束和/或旋转字符串之外进行读/写操作。旋转到输入中第一个元音的复制/填充方法示例如下所示:
/* 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
。根据{{1}}检查长度以确保足够的存储空间。
如果没有元音,则max
被复制到s
并返回指向rs
的指针,否则指针差异用于设置第一个元音的偏移索引,将第一个元音到结尾的字符串段复制到rs
,然后使用循环将前面的字符复制到rs
的末尾。 <{1}} nul-terminated 并返回指针。
虽然我很少建议使用rs
作为输入,但最好使用rs
后跟scanf
或fgets
),为了简短的例子,可用于从sscanf
读取单个字符串。注意:回答大/小写元音留给你。将最大字大小设置为32个字符(31个字符+ nul-terminatedating 字符)的简短示例将适用于未删节字典中的所有已知字词(最长字为28个字符):< / p>
strtok
示例使用/输出
(无耻地从WeatherVane stdin
#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;
}
仔细看看,如果您有任何疑问,请告诉我。注意:您可以在:)
语句之前调用$ echo "friend vwxyz aeiou" | ./bin/str_rot2vowel
friend => iendfr
vwxyz => vwxyz
aeiou => aeiou
函数并使用rot2vowel
打印结果,但由于函数返回指向字符串的指针,因此可以直接在printf
声明。你如何使用它取决于你。