| | |
Counting the amount of letters in a phrase!
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
Hi guys,
Just wanted to ask you're opinions about this program I had to write for evening school, the idea is when you enter a phrase wich isn't longer then 80 letters, the programm will count the amount of each letter wich is written :!:
It doesn't have to keep account of 'a' or 'A', and I had to show each letter of the alphabet, just in case you we're wondering.
So, if you could just give me some pointers
in wich way I could improve it, I would appreciate very much
// AantalLetters.cpp : Johan Berntzen: 11/11/2004
#include <stdafx.h>
#include <iostream.h>
#include <iomanip.h>
int zoek(const char s[], char ch);
void main(void)
{
int amount=0;
char str[80], letter='a';
cout<< " Write a phrase: ";
cin.getline(str,80);
for (int i=0;i<26;i++)
{
amount=zoek(str, letter);
cout<< letter << " = "<< amount;
cout<<setw(8);
if(i%7==6)cout<<endl;
letter++;
}
cin.get();
}
int zoek(const char s[], char ch)
{
short a=0;
for (int i=0;i<s[i];i++)
{
if (s[i]==ch)
a=++a;
}
return a;
}
Just wanted to ask you're opinions about this program I had to write for evening school, the idea is when you enter a phrase wich isn't longer then 80 letters, the programm will count the amount of each letter wich is written :!:
It doesn't have to keep account of 'a' or 'A', and I had to show each letter of the alphabet, just in case you we're wondering.
So, if you could just give me some pointers
in wich way I could improve it, I would appreciate very much
// AantalLetters.cpp : Johan Berntzen: 11/11/2004
#include <stdafx.h>
#include <iostream.h>
#include <iomanip.h>
int zoek(const char s[], char ch);
void main(void)
{
int amount=0;
char str[80], letter='a';
cout<< " Write a phrase: ";
cin.getline(str,80);
for (int i=0;i<26;i++)
{
amount=zoek(str, letter);
cout<< letter << " = "<< amount;
cout<<setw(8);
if(i%7==6)cout<<endl;
letter++;
}
cin.get();
}
int zoek(const char s[], char ch)
{
short a=0;
for (int i=0;i<s[i];i++)
{
if (s[i]==ch)
a=++a;
}
return a;
}
Before I make suggestions, I'll give you a cool version:
On to the code!
>#include <stdafx.h>
This should be a avoided because it makes your code nonportable. To be more specific, you can only compile code using stdafx.h with Visual Studio AFAIK.
>#include <iostream.h>
>#include <iomanip.h>
These are old headers that technically aren't a part of C++. Remove the .h extension and you'll have the standard headers, but don'e forget to qualify standard names with std::.
>void main(void)
int main(). main never has, and probably never will return void. You can safely omit the void parameter because it means the same thing as an empty list in C++ and it's kind of ugly.
>letter++;
This relies too much on the character set. ASCII is not the only character set in existence, and some don't have the alphabet in sequential order. On such character sets your code will break.
The biggest problem with your code is that it's running time is quadratic. For each letter in the alphabet, you look over every letter in the string. For long strings this is a dreadful inefficiency and you can easily remove it by using a frequency table. My code uses the standard map class, which implements a frequency table through a binary search tree, but you can also use arrays with very little effort.
C++ Syntax (Toggle Plain Text)
#include <algorithm> #include <iostream> #include <map> #include <utility> #include <string> using namespace std; map<char, int> get_frequency ( const string& s ); void show ( const pair<char, int>& freq_item ); int main() { string s; cout<<"Enter a string: "; if ( getline ( cin, s ) ) { map<char, int> freq = get_frequency ( s ); for_each ( freq.begin(), freq.end(), show ); } } map<char, int> get_frequency ( const string& s ) { string::const_iterator begin = s.begin(); string::const_iterator end = s.end(); map<char, int> freq; for ( string::const_iterator it = begin; it != end; ++it ) ++freq[*it]; return freq; } void show ( const pair<char, int>& freq_item ) { cout<< freq_item.first <<": "<< freq_item.second <<endl; }
>#include <stdafx.h>
This should be a avoided because it makes your code nonportable. To be more specific, you can only compile code using stdafx.h with Visual Studio AFAIK.
>#include <iostream.h>
>#include <iomanip.h>
These are old headers that technically aren't a part of C++. Remove the .h extension and you'll have the standard headers, but don'e forget to qualify standard names with std::.
>void main(void)
int main(). main never has, and probably never will return void. You can safely omit the void parameter because it means the same thing as an empty list in C++ and it's kind of ugly.
>letter++;
This relies too much on the character set. ASCII is not the only character set in existence, and some don't have the alphabet in sequential order. On such character sets your code will break.
The biggest problem with your code is that it's running time is quadratic. For each letter in the alphabet, you look over every letter in the string. For long strings this is a dreadful inefficiency and you can easily remove it by using a frequency table. My code uses the standard map class, which implements a frequency table through a binary search tree, but you can also use arrays with very little effort.
I'm here to prove you wrong.
Hi Narue,
Thanks for the example, but you know, I prefere to try and write my own
Thanks for the tip, I'll keep that in mind :!:
Now that is strange, we're being teached this way of programming and you say that it's the old way, can you explain this a bit more
So, if I understand correctly, it's better to start writing main with 'int main()' can you explain why because I'm not asking a return from main
Well, we we're told to use ASCII, so :o I'll have to do it with ASCII, I understand that in certain circumstances it is better to use another way. But for this program, do you think it is good enough
Well, that's my biggest problem aswell, in my code I have to use an array of 26 integers wich represent 0 to 25 and each number stands for one letter, problem is, I don't know how to solve that problem :rolleyes:
Also, is there a way that I can use my code, but altered in a manner that it doesn't have to go trough the loop so many times
To me it seems that now, the string allways has to go along with the letters each time it has to be checked :!: How could I change it in a manner that during the control of the letters the string stays put untill the total control of all numbers is done
•
•
•
•
Originally Posted by Narue
Before I make suggestions, I'll give you a cool version:
•
•
•
•
On to the code!
>#include <stdafx.h>
This should be a avoided because it makes your code nonportable. To be more specific, you can only compile code using stdafx.h with Visual Studio AFAIK.
•
•
•
•
>#include <iostream.h>
>#include <iomanip.h>
These are old headers that technically aren't a part of C++. Remove the .h extension and you'll have the standard headers, but don'e forget to qualify standard names with std::.
•
•
•
•
>void main(void)
int main(). main never has, and probably never will return void. You can safely omit the void parameter because it means the same thing as an empty list in C++ and it's kind of ugly.
•
•
•
•
>letter++;
This relies too much on the character set. ASCII is not the only character set in existence, and some don't have the alphabet in sequential order. On such character sets your code will break.
•
•
•
•
The biggest problem with your code is that it's running time is quadratic. For each letter in the alphabet, you look over every letter in the string. For long strings this is a dreadful inefficiency and you can easily remove it by using a frequency table. My code uses the standard map class, which implements a frequency table through a binary search tree, but you can also use arrays with very little effort.
Also, is there a way that I can use my code, but altered in a manner that it doesn't have to go trough the loop so many times
To me it seems that now, the string allways has to go along with the letters each time it has to be checked :!: How could I change it in a manner that during the control of the letters the string stays put untill the total control of all numbers is done
•
•
•
•
Now that is strange, we're being teached this way of programming and you say that it's the old way, can you explain this a bit more
Many books still use the old system only, as do older compilers.
And newer compilers still accept the old way as an alternative to remain compatible with old code. Many teachers just haven't caught on yet (if they even know, many teachers create their course at some point and never bother to keep it (and their own knowledge) up to date after that.
•
•
•
•
So, if I understand correctly, it's better to start writing main with 'int main()' can you explain why because I'm not asking a return from main
Every program needs to have a return code, with 0 meaning (on most operating systems) there was no error.
•
•
•
•
Well, we we're told to use ASCII, so I'll have to do it with ASCII, I understand that in certain circumstances it is better to use another way. But for this program, do you think it is good enough
@ jwenting, thanks for the explanation, I have no doubt that what I wrote would be unusable in other examples, but fact is, I have to use ASCII :o
It's our assignement :!:
@ Narue, am I correct when I say that your code is written in OO
Because this: map<char, int> get_frequency
and this: string::const_iterator begin = s.begin(); type of code, we haven't seen in structured programming.
We are going to start Object Oriented in one or two weeks :!:
Oh yes, going to order following books by the way:
- 3D Math Primer for Graphics and Game Development.
ISBN: 1556229119
- Essential Mathematics for Computer Graphics
ISBN: 1852333804
- Concrete Mathematics: A Foundation for Computer Science
ISBN: 0201558025
- Art of Computer Programming Volumes 1-3 Box set
ISBN: 0201558025
What do you think
It's our assignement :!:
@ Narue, am I correct when I say that your code is written in OO
Because this: map<char, int> get_frequency
and this: string::const_iterator begin = s.begin(); type of code, we haven't seen in structured programming.
We are going to start Object Oriented in one or two weeks :!:
Oh yes, going to order following books by the way:
- 3D Math Primer for Graphics and Game Development.
ISBN: 1556229119
- Essential Mathematics for Computer Graphics
ISBN: 1852333804
- Concrete Mathematics: A Foundation for Computer Science
ISBN: 0201558025
- Art of Computer Programming Volumes 1-3 Box set
ISBN: 0201558025
What do you think
Do you have the bible?
The C++ Programming Language 3rd edition (Stroustrup)? That's pretty much required fodder for everyone who's into C++.
I don't know any of the books you mention, but the titles sound like fun
I've ordered "C ++ for Game Programmers" last week which should arrive in a few days, got good reviews at gamedev.net. Some reviewers on Amazon complained there's not enough DX and graphics specific code in there but IMO that's a good thing as there's tons of books about that. Instead it focusses on things like performance and other generic stuff with applications in (among other things) games.
If you want a good intro on 3D mathematics on a 2D screen I can recommend "Flights of Fantasy" by Christopher Lampton. It's certainly been out of print for over a decade though, it still deals with DOS and 640x480x256 resolution but the explanations of the math involved are good. ISBN 1878739182 Waite Group, 1993. Maybe a second-hand bookstore or library clearout sale can turn it up.
I've also learned quite a bit from another oldie, a book on writing graphics drivers for DOS in Assembly and C (and in fact I've once written a partial functionality driver for Turbo Pascal, sadly never completed as the project was cancelled)...
For the rest I'm afraid most of my recent (say last 5 years) library has been Java books as that's what I mainly use professionally.
The C++ Programming Language 3rd edition (Stroustrup)? That's pretty much required fodder for everyone who's into C++.
I don't know any of the books you mention, but the titles sound like fun

I've ordered "C ++ for Game Programmers" last week which should arrive in a few days, got good reviews at gamedev.net. Some reviewers on Amazon complained there's not enough DX and graphics specific code in there but IMO that's a good thing as there's tons of books about that. Instead it focusses on things like performance and other generic stuff with applications in (among other things) games.
If you want a good intro on 3D mathematics on a 2D screen I can recommend "Flights of Fantasy" by Christopher Lampton. It's certainly been out of print for over a decade though, it still deals with DOS and 640x480x256 resolution but the explanations of the math involved are good. ISBN 1878739182 Waite Group, 1993. Maybe a second-hand bookstore or library clearout sale can turn it up.
I've also learned quite a bit from another oldie, a book on writing graphics drivers for DOS in Assembly and C (and in fact I've once written a partial functionality driver for Turbo Pascal, sadly never completed as the project was cancelled)...
For the rest I'm afraid most of my recent (say last 5 years) library has been Java books as that's what I mainly use professionally.
>but you know, I prefere to try and write my own
That's why I showed you an example that couldn't possibly be accepted as homework. It's just a way for me to show off.
>we're being teached this way of programming and you say that it's the old way, can you explain this a bit more
Before C++ was standardized, everyone basically agreed to use headers such as iostream.h as defined by The Annotated C++ Reference Manual written by Bjarne Stroustrup. When the language was standardized in 1998, these headers were edited heavily and the names were changed to remove the .h extension. You're being taught an old dialect of C++ that is quickly dying out.
>can you explain why because I'm not asking a return from main
If your compiler doesn't handle standard C++ then not returning a value from main results in undefined behavior. Undefined behavior is one of the worst things that your programs can have because it means they can do anything they like including (but not limited to) destructive operations on your computer such as wiping out data. Standard C++ defines main to return 0 (for success) if execution falls off the end, so you can omit a return statement safely.
However, just because you don't return a value explicitly doesn't mean that you can change the definition of main, which the standard states shall be (and when they use the word shall, you'd better do it or suffer undefined behavior):
Telling main to return void is undefined behavior, but in practice it's entirely possible that the program would simply fail to run if the run-time startup code sees a different call/return than it expected. Sadly, several systems support void main as an extension, but keep in mind that it's only an extension. Your code is not portable.
>Well, we we're told to use ASCII
You have to do what you have to do. Just remember that by assuming ASCII your code isn't as portable as it could be.
>I don't know how to solve that problem
ASCII letters are in sequential order. You can take advantage of that to create an array of 26 rather than an array of 128:
Otherwise you would need to account for every character in the character set, then discard what you don't want manually:
Neither is better than the other simply because the former is more efficient for your purposes, but the latter is efficient if you need a more general frequency table for the character set.
>And newer compilers still accept the old way as an alternative to remain compatible with old code.
This is changing though. For example, Visual Studio .NET fails to compile prestandard C++.
>It's not strictly required I think (the compiler won't complain after all)
It is strictly required, and a compiler that doesn't complain is probably set to allow non-standard extensions and void main is one of them. But when set to disable extensions, all decent compilers should flag a warning.
>with 0 meaning (on most operating systems) there was no error
0 is success for all implementations, on all systems, or it's not C++.
>Narue, am I correct when I say that your code is written in OO?
Yes and no. I make use of standard objects, but the term generic programming (through templates) would be more appropriate than object oriented programming in this case.
>- Art of Computer Programming Volumes 1-3 Box set
Good choice.
These are among my favorites. They're essential for any professional or hardcore hobbyist.
That's why I showed you an example that couldn't possibly be accepted as homework. It's just a way for me to show off.

>we're being teached this way of programming and you say that it's the old way, can you explain this a bit more
Before C++ was standardized, everyone basically agreed to use headers such as iostream.h as defined by The Annotated C++ Reference Manual written by Bjarne Stroustrup. When the language was standardized in 1998, these headers were edited heavily and the names were changed to remove the .h extension. You're being taught an old dialect of C++ that is quickly dying out.
>can you explain why because I'm not asking a return from main
If your compiler doesn't handle standard C++ then not returning a value from main results in undefined behavior. Undefined behavior is one of the worst things that your programs can have because it means they can do anything they like including (but not limited to) destructive operations on your computer such as wiping out data. Standard C++ defines main to return 0 (for success) if execution falls off the end, so you can omit a return statement safely.
However, just because you don't return a value explicitly doesn't mean that you can change the definition of main, which the standard states shall be (and when they use the word shall, you'd better do it or suffer undefined behavior):
C++ Syntax (Toggle Plain Text)
int main() or int main ( int argc, char *argv[] ) or anything equivalent
>Well, we we're told to use ASCII
You have to do what you have to do. Just remember that by assuming ASCII your code isn't as portable as it could be.
>I don't know how to solve that problem
ASCII letters are in sequential order. You can take advantage of that to create an array of 26 rather than an array of 128:
C++ Syntax (Toggle Plain Text)
#include <cctype> #include <iostream> using namespace std; int main() { char letters[] = "abcdefghijklmnopqrstuvwxyz"; int freq[sizeof letters - 1] = {0}; char str[80]; cout<<"Enter a string: "; if ( cin.getline ( str, sizeof str ) ) { for ( int i = 0; str[i] != '\0'; i++ ) { if ( isalpha ( str[i] ) ) ++freq[tolower ( str[i] ) - 'a']; } for ( int i = 0; letters[i] != '\0'; i++ ) { if ( freq[i] != 0 ) cout<< letters[i] <<": "<< freq[i] <<endl; } } }
C++ Syntax (Toggle Plain Text)
#include <cctype> #include <iostream> using namespace std; int main() { int freq[128] = {0}; char str[80]; cout<<"Enter a string: "; if ( cin.getline ( str, sizeof str ) ) { for ( int i = 0; str[i] != '\0'; i++ ) { if ( isalpha ( str[i] ) ) ++freq[tolower ( str[i] )]; } for ( int i = 0; i < 128; i++ ) { if ( isalpha ( static_cast<unsigned char> ( i ) ) && freq[i] != 0 ) cout<< static_cast<unsigned char> ( i ) <<": "<< freq[i] <<endl; } } }
>And newer compilers still accept the old way as an alternative to remain compatible with old code.
This is changing though. For example, Visual Studio .NET fails to compile prestandard C++.
>It's not strictly required I think (the compiler won't complain after all)
It is strictly required, and a compiler that doesn't complain is probably set to allow non-standard extensions and void main is one of them. But when set to disable extensions, all decent compilers should flag a warning.
>with 0 meaning (on most operating systems) there was no error
0 is success for all implementations, on all systems, or it's not C++.
>Narue, am I correct when I say that your code is written in OO?
Yes and no. I make use of standard objects, but the term generic programming (through templates) would be more appropriate than object oriented programming in this case.
>- Art of Computer Programming Volumes 1-3 Box set
Good choice.
These are among my favorites. They're essential for any professional or hardcore hobbyist. I'm here to prove you wrong.
>That's why I showed you an example that couldn't possibly be accepted as homework. It's just a way for me to show off. 
<<Oh, showboat LOL
>Before C++ was standardized, everyone basically agreed to use headers such as iostream.h as defined by The Annotated C++ Reference Manual written by Bjarne Stroustrup. When the language was standardized in 1998, these headers were edited heavily and the names were changed to remove the .h extension. You're being taught an old dialect of C++ that is quickly dying out.
<<Understood, I'll certainl mention this to him
>...returning a value from main results in undefined behavior.
<<Understood.
>You have to do what you have to do. Just remember that by assuming ASCII your code isn't as portable as it could be.
<<Well, for this excercise I'll use it, but will keep in mind of the portability problem with it!
>Neither is better than the other simply because the former is more efficient for your purposes, but the latter is efficient if you need a more general frequency table for the character set.
<<Thanks for the examples, In recoding my own, I'll surely will try and see how and more important why you did it in that certain way :!:
>Yes and no. I make use of standard objects, but the term generic programming (through templates) would be more appropriate than object oriented programming in this case.
<<Well, I'll try that type of coding out within a few months(years) :lol:
>Good choice.
These are among my favorites.
<< Well, you lead me to them
@jwenting, nope haven't got Stroustrup, I saw that it's last print was from 2000, little bit old don't you think?

<<Oh, showboat LOL
>Before C++ was standardized, everyone basically agreed to use headers such as iostream.h as defined by The Annotated C++ Reference Manual written by Bjarne Stroustrup. When the language was standardized in 1998, these headers were edited heavily and the names were changed to remove the .h extension. You're being taught an old dialect of C++ that is quickly dying out.
<<Understood, I'll certainl mention this to him
>...returning a value from main results in undefined behavior.
<<Understood.
>You have to do what you have to do. Just remember that by assuming ASCII your code isn't as portable as it could be.
<<Well, for this excercise I'll use it, but will keep in mind of the portability problem with it!
>Neither is better than the other simply because the former is more efficient for your purposes, but the latter is efficient if you need a more general frequency table for the character set.
<<Thanks for the examples, In recoding my own, I'll surely will try and see how and more important why you did it in that certain way :!:
>Yes and no. I make use of standard objects, but the term generic programming (through templates) would be more appropriate than object oriented programming in this case.
<<Well, I'll try that type of coding out within a few months(years) :lol:
>Good choice.
These are among my favorites. << Well, you lead me to them
@jwenting, nope haven't got Stroustrup, I saw that it's last print was from 2000, little bit old don't you think?
![]() |
Other Threads in the C++ Forum
- Previous Thread: Tutorials on Debugging
- Next Thread: Seg Fault from Matrix Data Constructor
| Thread Tools | Search this Thread |
api array based beginner binary bitmap c++ c/c++ calculator char char* class code coding compile compiler console conversion count database delete deploy desktop developer directshow dll download dynamic dynamiccharacterarray email encryption error file forms fstream function functions game givemetehcodez google graph gui homeworkhelp homeworkhelper iamthwee ifstream input int java lib linkedlist linker list loop looping loops map math memory multiple news node number numbertoword output parameter pointer problem program programming project python random read recursion recursive reference rpg sorting string strings temperature template templates test text text-file tree unix url variable vector video visualstudio win32 windows winsock word wordfrequency wxwidgets






