Why isn't this working correctly?

I

interpim

Just a quick exercise from my C programming book, that I can't figure out why it isn't working properly. It kinda works but im getting wierd output. It is supposed to remove the vowels from text.

#include <ctype.h>
#include <stdio.h>

int isvowel(int letter);

int main(void)
{
int letter;

while ((letter = getchar()) != EOF) {
if (isalpha(letter)) {
if (isvowel(letter))
getchar(letter);
else putchar(letter);
}
else putchar(letter);
}
return 0;
}

int isvowel(int letter)
{
if ( letter == 'A' || letter == 'E' || letter == 'I' || letter == 'O' || letter == 'U'
|| letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u')
return 1;
return 0;
}
 
B

Ben Pfaff

interpim said:
#include <ctype.h>
#include <stdio.h>

int isvowel(int letter);

Use a different name. Names that begin with `is' followed by a
lowercase letter are reserved.
int main(void)
{
int letter;

while ((letter = getchar()) != EOF) {

Read a character...
if (isalpha(letter)) {

....then if it's a letter...
if (isvowel(letter))

....and it's a vowel...
getchar(letter);

....read another character?

Do you see the problem? There's no need to read another
character.

Also, vowels are a subset of letters, so there's no need to call
isalpha() before calling isvowel().
 
K

Kevin Goodsell

interpim said:
Just a quick exercise from my C programming book, that I can't figure out why it isn't working properly. It kinda works but im getting wierd output. It is supposed to remove the vowels from text.

Please set your news client's line wrap to a reasonable value (72 or so).
#include <ctype.h>
#include <stdio.h>

int isvowel(int letter);

int main(void)
{
int letter;

while ((letter = getchar()) != EOF) {
if (isalpha(letter)) {
if (isvowel(letter))
getchar(letter);

You seem to be reading and discarding a character here. This does not
seem to match your specification. I think you wanted to say "if letter
is NOT a vowel, print it." If it is a vowel, you'd do nothing.

The whole thing could be simplified, though, by removing the isalpha
test completely, leaving only the isvowel test.
else putchar(letter);
}
else putchar(letter);
}
return 0;
}

int isvowel(int letter)
{
if ( letter == 'A' || letter == 'E' || letter == 'I' || letter == 'O' || letter == 'U'
|| letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u')

This could be simplified a bit by converting to uppercase first, then
comparing only against the uppercase vowels.
return 1;
return 0;
}

-Kevin
 
K

Kevin Goodsell

Kevin said:
You seem to be reading and discarding a character here.

On second thought, this should cause a compilation error. getchar does
not take any arguments.

-Kevin
 
M

Martin Dickopp

interpim said:
int isvowel(int letter);

Others have already answered your question. I would like to add that
function names that begin with `is' followed by a lowercase letter are
reserved for the implementation. To be safe, name your function `is_vowel'
or something similar.

Martin
 
K

Kevin Goodsell

Martin said:
Others have already answered your question. I would like to add that
function names that begin with `is' followed by a lowercase letter are
reserved for the implementation. To be safe, name your function `is_vowel'
or something similar.

I'd have to check to be sure, but I believe these are reserved for
future library use, not for the implementation's use.

-Kevin
 
B

Ben Pfaff

Kevin Goodsell said:
I'd have to check to be sure, but I believe these are reserved for
future library use, not for the implementation's use.

It amounts to the same thing, because in either case programs
cannot use them. Regardless of whether you use them to call a
function in the implementation under such a name or to name your
own function, it's undefined.
 
R

Richard Heathfield

Kevin said:
I'd have to check to be sure, but I believe these are reserved for
future library use, not for the implementation's use.

I just checked. You are correct, if 4.13 of the C89 draft is to be believed.
(I couldn't actually find this information in the C99 standard.)
 
K

Kevin Goodsell

Richard said:
I just checked. You are correct, if 4.13 of the C89 draft is to be believed.
(I couldn't actually find this information in the C99 standard.)

The corresponding section in C99 appears to be 7.26. Strange that you
couldn't find it, considering the section heading is the same ("Future
library directions"). Maybe there's something different in the final
document - I only have drafts.

-Kevin
 
C

CBFalconer

interpim said:
Just a quick exercise from my C programming book, that I can't
figure out why it isn't working properly. It kinda works but
im getting wierd output. It is supposed to remove the vowels
from text.

#include <ctype.h>
#include <stdio.h>

int isvowel(int letter);

int main(void)
{
int letter;

while ((letter = getchar()) != EOF) {
if (isalpha(letter)) {
if (isvowel(letter))
getchar(letter);
else putchar(letter);
}
else putchar(letter);
}
return 0;
}

int isvowel(int letter)
{
if ( letter == 'A' || letter == 'E' || letter == 'I'
|| letter == 'O' || letter == 'U'
|| letter == 'a' || letter == 'e' || letter == 'i'
|| letter == 'o' || letter == 'u')
return 1;
return 0;
}

Fix your linelength. Lines should not exceed 65 characters.

Ignoring the use of "isvowel" (you should choose another name
because that is reserved) your logic is unnecessarily contorted.
Try:

int main(void)
{
int letter;

while (EOF != (letter = getchar()))
if (!isvowel(letter) putchar(letter);
return 0;
}
 
J

Joona I Palaste

Why 65? I thought a standard terminal had 25 lines and 80 columns.

It's there to allow for those > marks in quoted messages. But I think
65 is overkill - 70 (or even 75 for dastardly types) is fine.
 
C

Christopher Benson-Manica

Grumble said:
Why 65? I thought a standard terminal had 25 lines and 80 columns.

Been asked by me already - Chuck's rationale (which I agreed with - I
now wrap at 65) is that doing so prevents one's text from exceeding 80
columns when it is quoted (and perhaps re-quoted, ad nauseum).
 
G

Grumble

Joona said:
It's there to allow for those > marks in quoted messages. But I think
65 is overkill - 70 (or even 75 for dastardly types) is fine.

Doh! I had not thought of that. It makes a lot of sense :)
 
S

stelios xanthakis

interpim said:
int isvowel(int letter)
{
if ( letter == 'A' || letter == 'E' || letter == 'I' || letter == 'O' || letter == 'U'
|| letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u')
return 1;
return 0;
}

It would be faster to map character classes to an array. Using c99 designators

static const int ctype_tbl [128] = {
['A']=1, ['E']=1, ['I']=1, ['O']=1, //etc for lower case
};

static inline int isvowel (int letter)
{
return ctype_tbl [letter] == 1;
}

Another solution would be switch-case

static inline int isvowel (int letter)
{
switch (letter)
case 'A': case 'a':
case 'E': case 'e':
case 'I': case 'i':
case 'O': case 'o':
return 1;
return 0;
}

compiler can do very good job running the switch in O(1).


stelios
 
D

Default User

Joona said:
It's there to allow for those > marks in quoted messages. But I think
65 is overkill - 70 (or even 75 for dastardly types) is fine.


Mine's at 72, which I had always heard was the prefered usenet length.



Brian Rodenborn
 
K

Kevin Goodsell

Christopher said:
Been asked by me already - Chuck's rationale (which I agreed with - I
now wrap at 65) is that doing so prevents one's text from exceeding 80
columns when it is quoted (and perhaps re-quoted, ad nauseum).

But that would require an awful lot of re-quoting. My line length is
currently 72, and that seems like it should be sufficient for all but
the most extreme cases. I could lower it though, if there's really a
good reason.

-Kevin
 
K

Keith Thompson

Christopher Benson-Manica said:
Been asked by me already - Chuck's rationale (which I agreed with - I
now wrap at 65) is that doing so prevents one's text from exceeding 80
columns when it is quoted (and perhaps re-quoted, ad nauseum).

Well, no, you don't; the second line of that paragraph is 70 columns
(72 now that I've quoted it). Which, in my opinion, is just fine.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top