Comparison of string - c

I've been sitting on a code for almost ten days right now.
I am writing a funtion that get two pointers for 2 different strings, and the function need to return 1 if there is the same number of words, or 0 if there isnt.
I am not allowed to use any lib, global or static int etc, no loops, only recursion, not allowed to change the signature of the function.
what I wrote is the delta between the two sentences. First my code calculates the sum of words in the first sentence, when it gets to the '\0' of the first sentence, it starts to work on the second sentence, and substract each time there is a word.
right now the output of my funtion is the delta, I want somehow to tell the function that if the delta ("the return") is 0 return 1, else return 1.
"
int same_num_words(char *s1, char *s2)
{
printf("%s\n", s1);
printf("%s\n", s2);
if(s1[0]=='\0' && s2[0] == '\0')
{
return 0;
}
if (s1[0] == '\0' ) // AFTER first sentence is complete, substract the second sentence count.
{
if(s2[0]!= ' ' && s2[1]== ' ')
{
return same_num_words(s1, s2+1) -1 ;
}
if(s2[0]!= ' ' && s2[1]== '\0')
{
return same_num_words(s1, s2+1)-1;
}
return same_num_words(s1, s2+1);
}
if(s1[0]!='\0') // first sentence
{
if((s1[0]!= ' ' && s1[1]== ' ') || (s1[0]!= ' ' && s1[1]== '\0') ) // first sentence
{
return same_num_words(s1+1, s2)+1;
}
}
return same_num_words(s1+1, s2);
}
"
any help?

Each character is either a letter or delimiter ('\0' or whitespace: space, \n \t, etc)
1 - Any leading whitespace is irrelevant, so skip over those.
2 - If code is at the end of either string, we are done.
3 - Since each string now begins with a letter, see it the next character is also a letter.
int same_num_words(const char *s1, const char *s2) {
// printf("'%s' ", s1);
// printf("'%s'\n", s2);
if (s1[0] == ' ') return same_num_words(s1 + 1, s2);
if (s2[0] == ' ') return same_num_words(s1, s2 + 1);
if (s1[0] == '\0' && s2[0] == '\0') return 1; // same
if (s1[0] == '\0') return 0; // differ
if (s2[0] == '\0') return 0;
// Both s1,s2 begin with a letter (non-delimiter)
// If the next character is also a letter, skip over the current one.
// as code is looking for the end-of-word.
if (!(s1[1] == '\0' || s1[1] == ' ')) return same_num_words(s1+1, s2);
if (!(s2[1] == '\0' || s2[1] == ' ')) return same_num_words(s1, s2+1);
return same_num_words(s1+1, s2+1);
}
Expand s1[0] == ' ' to s1[0] == ' ' || s1[0] == '\t' || ... as needed.
A key change from OP code was skipping leading spaces first as that consumes the string's leading and trailing spaces.
For fun, a cleaner looking implementation with typically fewer recursions.
int same_num_words(const char *s1, const char *s2) {
int sp1 = *s1 == ' ';
int sp2 = *s2 == ' ';
if (sp1 | sp2) return same_num_words(s1 + sp1, s2 + sp2);
int nc1 = *s1 == '\0';
int nc2 = *s2 == '\0';
if (nc1 | nc2) return nc1 & nc2;
// Both s1,s2 begin with a letter (non-delimiter)
// How about the next character?
int nxt_let1 = !(s1[1] == '\0' || s1[1] == ' ');
int nxt_let2 = !(s2[1] == '\0' || s2[1] == ' ');
if (nxt_let1 | nxt_let2) return same_num_words(s1 + nxt_let1, s2 + nxt_let2);
return same_num_words(s1 + 1, s2 + 1);
}

This solution obeys the letter of the rules (although I did add some const). It overloads the meaning of same_num_words to return the number of words in the string if either of the arguments is NULL. The second argument is NULL if the previous character read (if any) was space, and the first argument NULL if we've just read a word character.
int same_num_words(const char *s1, const char *s2) {
if (!s1 || !s2) {
const char *s = s1 ? s1 : s2;
if (*s == '\0') return !s1;
if (*s == ' ') return !s1 + same_num_words(s + 1, 0);
return same_num_words(0, s + 1);
}
return same_num_words(s1, 0) == same_num_words(s2, 0);
}
Here's some unit tests to check the implementation.
#include <assert.h>
#include <stdio.h>
int main(int argc, char **argv) {
struct {
const char *word1;
const char *word2;
int want;
} cases[] = {
{"This is a test", "one two three four", 1},
{"", "", 1},
{"one", "", 0},
{" one two three ", "one two three", 1},
{"one two three ", "one two three", 1},
{"one two three ", "one two three four", 0},
{" ", "", 1},
};
int failed = 0;
for (int i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
int got = same_num_words(cases[i].word1, cases[i].word2);
if (got != cases[i].want) {
printf("same_num_words('%s', '%s') = %d, want %d\n", cases[i].word1, cases[i].word2, got, cases[i].want);
failed = 1;
}
got = same_num_words(cases[i].word2, cases[i].word1);
if (got != cases[i].want) {
printf("same_num_words('%s', '%s') = %d, want %d\n", cases[i].word2, cases[i].word1, got, cases[i].want);
failed = 1;
}
}
assert(!failed);
return 0;
}

Try this:
int check_words(char *str1, char*str2) {
if (!str1 && !str2) {
return 1;
}
if (!str1 || !str2) {
return 0;
}
if (*str1=='\0' && *str2=='\0') {
return 1;
}
if((*str1==' ' || *str1=='\t') && (!(*str2==' ' || *str2=='\t' || *str2=='\0')))
return check_words(str2+1, str1);
if((*str2==' ' || *str2=='\t') && (!(*str1==' ' || *str1=='\t' || *str1=='\0')))
return check_words(str1+1, str2);
if (*str1=='\0' && (*str2==' ' || *str2=='\t')) {
return check_words(str1, str2+1);
}
if (*str2=='\0' && (*str1==' ' || *str1=='\t')) {
return check_words(str2, str1+1);
}
if (*str1!='\0' && *str2!='\0') {
return check_words(str1+1, str2+1);
}
else {
return 0;
}
}

Related

How many this word in the array string

I want to count how many this word and operator in the string but I try to use strchr and it doesn't work.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
int x,count =0;
char buff[100]="1+2.3(7^8)sin cos + cos sin_e-2x+x2*2!/_x1 sine";
//gets(buff);
strupr(buff);
for (int i = 0; buff[i] != '\0'; i++)
{
if (buff[i] == '+' || buff[i] == '-' || buff[i] == '*' ||
buff[i] == '/' || buff[i] == '^'|| buff[i] == '(')
{
count++;
}
}
char *op2;
int check=0;
char cpysin[100],cpycos[100];
strcpy(cpysin,buff);
strcpy(cpycos,buff);
do
{
if(strchr(cpysin,'SIN')!=0)
{
count++;
strcpy(cpysin,strstr(cpysin,"SIN"));
cpysin[0] = ' ';
cpysin[1] = ' ';
cpysin[2] = ' ';
}
else
{
break;
}
}
while(check==0);
do
{
if(strchr(cpycos,'COS')!=0)
{
count++;
strcpy(cpycos,strstr(cpycos,"COS"));
cpycos[0] = ' ';
cpycos[1] = ' ';
cpycos[2] = ' ';
}
else
{
break;
}
}
while(check==0);
printf("FINAL \n%d",count);
}
I only work when I do it in the loop while trying to find how many sins are in there but it doesn't work when I put cos function on it. Please tell me how to fix this and what if I need to write more functions to find.
strchr(cpysin, 'SIN') is wrong.
Unfortunately the compiler may not give you a warning because 'SIN' can be interpreted as 4 byte integer. The second parameter is supposed to be an integer, but strchr really wants character, it chops it off to 'N'
Just remember that in C you work with single characters 'a' or strings "cos" (or you can come accross wide characters/strings)
Use strstr to find a string. For example, to find "cos":
char* ptr = buff;
char* find = strstr(ptr, "cos");
"1+2.3(7^8)sin cos + cos sin_e-2x+x2*2!/_x1 sine";
---------------^ <- find
find will point to "cos + cos sin_e-2x+x2*2!/_x1 sine"
You can increment ptr and look for the next occurrence of "cos".
Also note, you can declare char buff[] = "...", you don't have to assign the buffer size.
char buff[] = "1+2.3(7^8)sin cos + cos sin_e-2x+x2*2!/_x1 sine";
int count = 0;
const char* ptr = buff;
const char* text = "cos";
//must terminate when ptr reaches '\0' which is at the end of buff
//there is serious problem if we read past it
while(*ptr != '\0')
{
char* find = strstr(ptr, text);
if (find != NULL)
{
printf("update [%s]\n", find);
count++;
ptr = find + strlen(text);
//next search starts after
}
else
{
ptr++;
//next character start at next character
}
}
printf("%s count: %d\n", text, count);

palindrome c program is not working for some reason

this program checks weather the entered string is palindrome or not . it should be in a way like it should even tell the string is palindrome if there is space or any special character
like messi is a palindrome of iss em
and ronald!o is a palindrome of odlanor
this is the program and for some odd reason it is strucking and not working
#include <stdio.h>
#include <string.h>
int main() {
char palstr[100], ans[100];
printf("enter the string for checking weather the string is a palindrome or not");
scanf("%[^/n]", &palstr);
int ispalin = 1, i = 0, n = 0;
int num = strlen(palstr);
printf("the total length of the string is %d", num);
while (i <= num) {
if (palstr[i] == ' ' || palstr[i] == ',' || palstr[i] == '.' ||
palstr[i] == '!' || palstr[i] == '?') {
i++;
}
palstr[n++] == palstr[i++];
}
int j = num;
i = 0;
while (i <= num) {
ans[j--] = palstr[i];
}
printf("the reverse of the string %s is %s", palstr, ans);
if (ans == palstr)
printf("the string is a palindrome");
else
printf("the string is not a palindrome");
return 0;
}
A few points to consider. First, regarding the code:
if (ans == palstr)
This is not how you compare strings in C, it compares the addresses of the strings, which are always different in this case.
The correct way to compare strings is:
if (strcmp(ans, palstr) == 0)
Second, you should work out the length of the string after you have removed all unwanted characters since that's the length you'll be working with. By that I mean something like:
char *src = palstr, dst = palstr;
while (*src != '\0') {
if (*c != ' ' && *src != ',' && *src != '.' && *src != '!' && *src != '?') {
*dst++ = *src;
}
src++;
}
Third, you have a bug in your while loop anyway in that, if you get two consecutive bad characters, you will only remove the first (since your if does that then blindly copies the next character regardless).
Fourth, you may want to consider just stripping out all non-alpha characters rather than that small selection:
#include <ctype.h>
if (! isalpha(*src) {
*dst++ = *src;
}
Fifth and finally, you don't really need to create a new string to check for a palindrome (though you may still need to if you want to print the string in reverse), you can just start at both ends and move inward, something like:
char *left = &palstr, right = palstr + strlen(palstr) - 1, ispalin = 1;
while (left < right) {
if (*left++ != *right--) {
ispalin = 0;
break;
}
}
There may be other things I've missed but that should be enough to start on.
well, the are so many bugs in this code. I will point them out with comments.
#include <stdio.h>
#include <string.h>
int main() {
char palstr[100], ans[100];
printf("enter the string for checking weather the string is a palindrome or not\n");
scanf("%s", palstr); // your former code won't stop input util Ctrl+D
int ispalin = 1, i = 0, n = 0;
int num = strlen(palstr);
printf("the total length of the string is %d\n", num);
while (i < num) { // < insted of <=
if (palstr[i] == ' ' || palstr[i] == ',' || palstr[i] == '.' ||
palstr[i] == '!' || palstr[i] == '?') {
i++;
continue;// without this, marks still in the string
}
palstr[n++] = palstr[i++]; //should be =
}
palstr[n] = '\0'; //
num = n; // the length might be changed
i = 0;
int j = num-1; // reverse
while (i < num) { //
ans[i++] = palstr[j--]; //
}
ans[i] = '\0'; //
printf("the reverse of the string %s is %s\n", palstr, ans);
//if (ans == palstr) they can never be equal
if (strcmp(ans, palstr)==0)
printf("the string is a palindrome\n");
else
printf("the string is not a palindrome\n");
return 0;
}

How to write a program that inputs a word and count how many times the word appearing in given strings in C?

Input word
1.Does not contain any spaces.
2.Less than 15 characters.
Keep this things
1.Case sensitive
2.DO NOT use ‘string.h’.
3.Only the ‘stdio.h’ is allowed.
#include<stdio.h>
int search(const char* str1, const char* str2)
int main(void)
{
char input[15];
char string1[400] = " Pinot noir is a red wine grape variety of the species Vitisvinifera. The name may also refer to wines created predominantly from Pinot noir grapes. The name is derived from the French words for pine and black. The word pine alludes to the grape variety having tightly clustered, pine cone-shaped bunches of fruit.[1].";
char string2[400] = " Metallica is an American heavy metal band. The band was formed in 1981 in Los Angeles by vocalist/guitarist James Hetfield and drummer Lars Ulrich, and has been based in San Francisco for most of its career.[1][2] The band's fast tempos, instrumentals and aggressive musicianship made them one of the founding big four bands of thrash metal, alongside Megadeth, Anthrax and Slayer.";
printf("string1: %s\n\n", string1);
printf("string2: %s\n\n", string2);
printf("Enter a word to count:");
scanf("%s", input);
printf("'%s' is found %d times in the string1.\n", input, search(input, string1));
printf("'%s' is found %d times in the string2.\n", input, search(input, string2));
return 0;
}
int mystrlen(const char* str)
{
int i = 0;
while (*str != '\0') {
*(str++);
i++;
}
return i;
}
int search(const char* str1, const char* str2)
{
int result = 0;
int len = mystrlen(str1);
while (*str2 != '\0') {
if (*str2 == *str1) {
while (*str1 != '\0') {
if (*(s1++) != *(s2++))
result = result * 1;
}
if (*(str2--) != ' ' || *str2 + len != ' ')
result = result * 1;
else if (*str2 + len == '.' || *str2 + len == ',')
result++;
result++;
}
*(str2++);
}
return result;
}
EXAMPLE
string1: " Pinot noir is a red wine grape variety of the species Vitisvinifera. The name may also refer to wines created predominantly from Pinot noir grapes. The name is derived from the French words for pine and black. The word pine alludes to the grape variety having tightly clustered, pine cone-shaped bunches of fruit.[1].";
string2:" Metallica is an American heavy metal band. The band was formed in 1981 in Los Angeles by vocalist/guitarist James Hetfield and drummer Lars Ulrich, and has been based in San Francisco for most of its career.[1][2] The band's fast tempos, instrumentals and aggressive musicianship made them one of the founding big four bands of thrash metal, alongside Megadeth, Anthrax and Slayer.";
Enter a word to count: is
'is' is found 2 times in string 1.
'is' is found 1 times in string 2.
I couldn't understand your search function and I thought your function didn't cover some cases like if word is immediately followed by question mark or semicolon. I have included some of those cases too.
#include <stdio.h>
// Find length of a char string
int mystrlen(const char* str)
{
int i = 0;
while (*str != '\0') {
str++;
i++;
}
return i;
}
// Find count of str1 in str2
int search(const char* str1, const char* str2)
{
int cnt = 0,
i = 0,
j = 0,
len = mystrlen(str1);
for (i = 0; str2[i] != '\0'; i++) {
if (str1[j] == str2[i]) {
// if last char of str1 then check next char in str2
// is followed by either space or . or ? or ! or , or ; or :
// If yes, then a match is found
if (j == len - 1
&& str2[i + 1] != '\0'
&& (str2[i + 1] == ' '
|| str2[i + 1] == '.'
|| str2[i + 1] == '?'
|| str2[i + 1] == '!'
|| str2[i + 1] == ','
|| str2[i + 1] == ';'
|| str2[i + 1] == ':'))
cnt++;
// if not last char of str2, increment j to check for next char
else j++;
}
// if not matched with current char of str2, reset j
else j = 0;
}
return cnt;
}
int main(void) {
int cnt = search("island", "That is my island, isn't it?");
printf("island appeared %d times\n", cnt);
return 0;
}
Here's the link where I tested it: https://ideone.com/BPbQwh

Function to count the amount of times two string match in C

I'm trying to find how may times two string matches in c, if we have two or more stars, multiple string combination can be suitable. e.g "abcdb" & "*b*" matches two times. my current code works but it returns four. I don't what I am missing here.
#include <stdio.h>
int nmatch(char *s1, char *s2) {
if (*s1 != '\0' && *s2 != '\0' && *s2 == '*' && (*s2 + 1) != *s1) {
return nmatch(s1 + 1, s2) + 1;
}
if (*s1 == *s2) {
return nmatch(s1 + 1, s2 + 1);
}
if (*s1 == *s2 && *s1 == '\0' && *s2 == '\0') {
return 0;
}
return (1);
}
int main() {
char ap[] = "abcd";
char ab[] = "*b*";
printf("%d", nmatch(ap, ab));
return 0;
}
Your code just does not count the number of different ways s1 matches pattern s2. It does not even return 1 for identical strings.
The first comparison (*s2 + 1) != *s1 is incorrect, you probably meant *(s2 + 1) != *s1 equivalent to s2[1] != *s1, but this fix is not enough to correct the algorithm.
Here is a naive implementation that does:
int nmatch(const char *s1, const char *s2) {
int count;
while (*s2 != '\0' && *s2 != '*' && *s1 == *s2) {
s1++;
s2++;
}
if (*s2 == '\0')
return *s1 == '\0';
if (*s2 != '*')
return 0;
while (*s2 == '*') /* skip all stars */
s2++;
if (*s2 == '\0')
return 1;
for (count = 0;; s1++) {
count += nmatch(s1, s2);
if (*s1 == '\0')
break;
}
return count;
}
I think your algorithm is just wrong. Together with the flawed implementation this will lead no where.
There's the input string and the pattern string. If the first character of the pattern is not a * and is not equal to the first character of the input string, then return 0 (it's a mismatch).
If they're equal, then remove the first character of both the input and the pattern and return the number of matches of the reduced input and pattern.
On the other hand, if the first character of the pattern is a *, then (in a loop) sum the number of matches of the remaining pattern with the complete input string, the input string without the first, then without the second character ... and so on until the input string is empty.
If both input and pattern are empty: return 1. If only one of the strings is empty: return 0.
I implemented it as direct recursive function (for production use that should be changed into an iterative version):
unsigned matches(char const * const input, char const * const pattern) {
if (! *pattern) {
// An empty pattern matches only the empty
// string, nothing else
return (*input) ? 0 : 1;
}
if (*pattern == '*') {
// a wildcard could be zero to any number
// of characters. Sum the number of matches
// for each possibility (excluding the empty
// rest of input for now)
char const * rest = input;
unsigned count = 0;
while (*rest) {
count += matches(rest, pattern + 1);
++rest;
}
// Add matches for the empty rest of input
count += matches(rest, pattern + 1);
return count;
}
if (! *input) {
// A non empty, non wildcard pattern cannot
// match the empty string
return 0;
}
if (*pattern == *input) {
// non wildcard match, count the ways the rest of
// the pattern matches the rest of the input.
return matches(input + 1, pattern + 1);
}
else {
// mismatch!
return 0;
}
}
(Live with tests)
To deal with the combinatory explosion of possible matches when there are multiple adjacent wildcards in the pattern one could remove these from the pattern first.

Find Word with Vowels in order C

So for a lab at uni... Ive been challenged to find all words in the usr/share/dict/linux.words
file using fopen, fgets etc with every vowel only once, in order.
i.e. facetious
So far I have the following code... but its flawed somewhere...
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;
}
Any tips would be great!!!
Im really confused at the moment...
You are accessing v as if it were pointing to a location holding a number of characters, when indeed you only reserve space for one single char * (usually 4 byte on a 32 bit machine and 8 byte on a 64 bit machine):
char *v = malloc(sizeof(char *));
That might or might not be enough for what you are trying to store in it; in your case, the number of vowels, in any given word.
Whenever possible, you should avoid dynamic allocations; in your case, you don't need them, you can declare an array of fixed size instead of a char*:
char v[5];
In addition to that, you have to check if you have read 5 vowels already, so that you don't exceed the array size; if, after 5 vowels, you encounter another one, you can stop the check anyway; the currently encountered one has to be a duplicate vowel, the word will therefore not qualify.
The way you address characters is also a problem. Check again what * does: it dereferences the expression immediately to the right. In your case, it will always dereference v, then add something to it (which is also legal, since the result of dereferencing is a char). So if the first character where v points to is an a, the second an e, then *v will yield 'a', (*v + 1) will yield 'b', (*v +2) will yield 'c' and so on - you see, the result is an addition to the letter a by the given number; it doesn't matter at all what comes after the first character because you never access the value there. To achieve what you want with pointer arithmetic, you'd have to use parenthesis: *(v+1) - i.e., add 1 to the pointer v, then dereference it. This would yield the second character in the c string starting at v, i.e. 'e'.
Note that with v declared as above you can simply write v[0], v[1], v[2] and so on to address each character.
Aside from that, check the last comparison in your if condition, you had an 'e' instead of an 'u' there.
By the way, as a side note, and something to think about: There is a solution to your problem which does not require the v/vowel variables at all... only a single integer variable!
but its flawed somewhere...
Could there be an error here?
if ( *vowel == 'a' &&
(*vowel + 1) == 'e' &&
(*vowel + 2) == 'i' &&
(*vowel + 3) == 'o' &&
(*vowel + 4) == 'e' )
// ^^^ 'u'?
There may also be other errors. I haven't checked all your code.
Here is a big flaw:
char *v = malloc(sizeof(char *));
This only allocates four or eight bytes (depending on if you are on a 32 or 64 bit platform). I'm guessing you want a little more than that.
PS. In the future, you should probably try to be more specific instead of just saying that "it's flawed".
Why is all_vowels() allocating memory? And, even more interesting, why doesn't it free() it?
I'm pretty sure all_vowels() doesn't have to allocate any memory, and can be a bit simpler than what you have.
Also, you can´t use feof() before trying to read from the file. Remove that, just loop until fgets() returns NULL.
I would probably write a helper function int is_vowel(char c); to make the code clearer, and then attack the problem like so in 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
Okay.. So I finally got the right output... Any hints or tips for greater efficiency would be much appreciated.
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;
}
little unsure regarding parseing your file yet i function(s) below check that a character is a vowel and tests whether the next vowel is greater then the current vowel.
#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;
}
demo

Resources