[英]Find Word with Vowels in order C
因此,对于在大学的实验室来说,我遇到了挑战,即使用fopen,fgets等对每个元音仅按顺序查找usr / share / dict / linux.words文件中的所有单词。
即刻薄
到目前为止,我有以下代码...但是它在某处存在缺陷...
int all_vowels( char *s )
{
const unsigned char *p = (const unsigned char *)s;
char *v = malloc(sizeof(char *));
char *vowel = v;
if(*p == '\0') return -1;
while( *p != '\0' )
{
if( *p == 'a' || *p =='e' || *p =='i'|| *p =='o' || *p =='u' )
{
*v = *p;
v++;
}
p++;
}
if ( *vowel == 'a' && (*vowel + 1) == 'e' && (*vowel + 2) == 'i' && (*vowel + 3) == 'o' && (*vowel + 4) == 'u' )
{
return 1;
}
return -1;
}
int main (int argc, char *argv[])
{
FILE *file;
char line[BUFSIZ];
if (( file = fopen("/usr/share/dict/words", "r") ) == NULL)
{
fprintf(stderr, "cannot open %s\n", "/usr/share/dict/words");
exit(1);
}
while ( !feof(file) )
{
fgets(line, sizeof(line), file);
if ( all_vowels(line) == 1 )
{
printf("%s\n", line);
}
}
fclose(file);
return 0;
}
任何提示都很棒!!!
我现在真的很困惑...
但它在某处存在缺陷
这里可能有错误吗?
if ( *vowel == 'a' &&
(*vowel + 1) == 'e' &&
(*vowel + 2) == 'i' &&
(*vowel + 3) == 'o' &&
(*vowel + 4) == 'e' )
// ^^^ 'u'?
可能还存在其他错误。 我尚未检查所有代码。
这是一个很大的缺陷:
char *v = malloc(sizeof(char *));
这只会分配四个或八个字节(取决于您是在32位还是64位平台上)。 我猜您想要的更多。
PS。 将来,您可能应该尝试更加具体,而不仅仅是说“它有缺陷”。
您访问v
就像指向一个包含多个字符的位置一样,而实际上您只为单个char *
(在32位计算机上通常为4个字节,在64位计算机上通常为8个字节)保留空间:
char *v = malloc(sizeof(char *));
对于您要存储在其中的内容,这可能足够,也可能不够; 在您的情况下,任何给定单词中的元音数量。
只要有可能,就应该避免动态分配。 在您的情况下,您不需要它们,可以声明一个固定大小的数组而不是char *:
char v[5];
除此之外,您还必须检查是否已经读过5个元音,以免超出数组大小; 如果在5个元音之后遇到另一个,您仍然可以停止检查; 当前遇到的一个元音必须是重复的元音,因此该词将不合格。
您处理字符的方式也是一个问题。 再次检查*
作用:它立即在右侧取消引用表达式。 在您的情况下,它将始终取消引用v,然后向其添加某些内容(这也是合法的,因为取消引用的结果为char)。 因此,如果v指向的第一个字符是a,第二个字符是e,则*v
将产生'a'
, (*v + 1)
将产生'b'
, (*v +2)
将产生'c'
依此类推-您将看到结果是给定数字加上字母a; 紧跟第一个字符之后的内容根本没有关系,因为您永远不会访问那里的值。 要使用指针算术实现所需的功能,必须使用括号: *(v+1)
-即,将1加到指针v
,然后对其取消引用。 这将产生从v
开始的c字符串中的第二个字符,即'e'
。 请注意,使用如上所述声明的v,您可以简单地编写v[0]
, v[1]
, v[2]
等来寻址每个字符。
除此之外,检查if条件中的最后一个比较,那里有一个“ e”而不是“ u”。
顺便说一句,作为附带说明,还有一些需要考虑的问题:有一种解决方案,根本不需要v
/ vowel
变量……只需要一个整数变量!
为什么all_vowels()
分配内存? 而且,更有趣的是,为什么不使用free()
呢?
我很确定all_vowels()
不必分配任何内存,并且可以比您拥有的内存简单一些。
另外, 在尝试读取文件之前 ,不能使用feof()
。 删除它,循环直到fgets()
返回NULL
。
我可能会写一个辅助函数int is_vowel(char c);
使代码更清晰,然后在all_vowels()
像这样解决问题:
vowels = "aeiou"
for each character x in the string to check:
if is_vowel(x):
if vowels starts with x:
let vowels = vowels[1:]
else
return false
return true if vowels is empty
好吧..所以我终于得到了正确的输出...对于提高效率的任何提示或技巧将不胜感激。
int all_vowels( char *s )
{
const unsigned char *p = (const unsigned char *)s;
char v[5];
int i = 0;
if(*p == '\0') return -1;
while( *p != '\0' )
{
if( (*p == 'a' || *p =='e' || *p =='i'|| *p =='o' || *p =='u') && ( i < 5 ) )
{
v[i] = *p;
i++;
}
p++;
}
if ( ( v[0] == 'a' && v[1] == 'e' && v[2] == 'i' && v[3] == 'o' && v[4] == 'u' ) && (strlen(v) == 5 ))
{
return 1;
}
return -1;
}
int main (int argc, char *argv[])
{
FILE *file;
char line[30];
if (( file = fopen("/usr/share/dict/words", "r") ) == NULL)
{
fprintf(stderr, "cannot open %s\n", "/usr/share/dict/words");
exit(1);
}
while ( fgets(line, sizeof(line), file) )
{
if ( all_vowels(line) == 1 )
{
printf("%s\n", line);
}
}
fclose(file);
return 0;
}
关于解析您的文件有点不确定,但是我在下面的功能中检查字符是否是元音,并测试下一个元音是否大于当前元音。
#include <stdio.h>
// for readability not advocating the
// usage of #define booleans etc
#define TRUE 1
#define FALSE 0
int isVowel (char c)
{
switch (c)
{
case 'a': return TRUE;
case 'e': return TRUE;
case 'i': return TRUE;
case 'o': return TRUE;
case 'u': return TRUE;
case 'A': return TRUE;
case 'E': return TRUE;
case 'I': return TRUE;
case 'O': return TRUE;
case 'U': return TRUE;
}
return FALSE;
}
int hasOrderedVowels (char *str)
{
char c1, c2;
c1 = *str;
c2 = *(++str);
// ignore words beginning in vowels other then 'a' or 'A'
if (isVowel(c1) && !(c1 == 'a' || c1 == 'A')) return FALSE;
do {
// ignore case of `c1`
if (c1 >= 'a')
c1 -= 32;
// ignore case of `c2`
if (c2 >= 'a')
c2 -= 32;
// compare vowels and increment
// pointers as appropriate
if (isVowel(c1) && isVowel(c2))
{
// if we have found a vowel less then or equal to current
// then they are not in order/more then one, if we have found
// a 'U' and there are more vowels then this would be a duplicate
if (c2 <= c1 || c1 == 'U')
return FALSE;
c1 = c2;
}
else if (isVowel(c2)) // found first vowel so assign to c1
{
if (!(c1 == 'a' || c1 == 'A'))
{
return FALSE;
}
c1 = c2;
}
else if (!isVowel(c1))
{
c1 = *(str += 2); // skip over c2
}
c2 = *(++str);
}
while (c2 != '\0');
return (c1 == 'U');
}
int main ()
{
char *str[] = {"aeiou", "facecious", "chimpanze", "baboon"};
int i = 0;
for (; i<5; i++)
{
printf ("%s: %i\n", str[i], hasOrderedVowels(str[i]));
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.