2

I've been struggling with a homework assignment that counts the amount of instances a uppercase letters, lowercase letters, and numbers in a string. appears in a string.

I'm using a one-dimensional array with a constant size of 132 to store the entered string, and I need to use two functions. One needs to count the amount of letter occurrences in the string and the other function will execute the output something similar to above. I'm struggling most with the letter counting aspect of the program itself.

Currently, this is what my current homework resembles for the most part. It's a work in progress (of course) so errors in the code are very likely.

void LetterCount(char c_input[], int l_count)
{
// code to count letters
}

void CountOut(//not sure what should go here yet until counting gets figured out)
{
// code that handles output
}

int main()
{
    const int SIZE = 132;
    char CharInput[SIZE];
    int LetterCount = 0;
    cout << "Enter a string of up to 132 characters in size: ";
    cin.getline(CharInput, SIZE); 
    cout << "You entered: " << CharInput << endl;

    Count(CharInput);
    CountOut(//not sure what goes here yet);
    return 0;
}

The output would look something like:

  a - 2
  b - 1
  c - 1
  d - 0
  e - 1

etc...

I've tried some experimentation with for loops to count the letters and have seen some examples of the function gcount(), but I haven't gotten anything to work. Does anyone have a suggestion as to how I would count the letters in an inputted string?

Milo Lu
  • 3,176
  • 3
  • 35
  • 46
BIG PUPPO
  • 23
  • 5
  • post what code you have, gcount() doesn't sound applicable to me. are you unable to read individual characters? or is adding them to the array giving you trouble? – kmdreko Oct 16 '18 at 02:22
  • Ive posted the code that I have at the moment. I'm struggling to read the occurences of each individual letter within the entered string. – BIG PUPPO Oct 16 '18 at 02:28
  • This doesn't address the question, but when you're reading input into an array that holds 132 characters, you can't read more than **131** characters. `getline` stops at one less than the size argument and puts a nul terminator at the end of the input. – Pete Becker Oct 16 '18 at 13:19

4 Answers4

5

map is a very efficient data structure here

#include <iostream>
#include <map>
using namespace std;

int main(){
    string str = "a boy caught 2 fireflies";
    map<char, int> str_map;
    for(auto x : str) ++str_map[x];
    for(auto x : str_map) cout << x.first << ' ' << x.second << '\n';
}
Milo Lu
  • 3,176
  • 3
  • 35
  • 46
  • this won't list out characters that did not occur (`d - 0` from post) – kmdreko Oct 16 '18 at 02:45
  • @kmdreko Indeed. The solution is not complete. I will leave it to the OP :) – Milo Lu Oct 16 '18 at 02:52
  • 3
    @kmdreko that is a simple fix by changing the second loop to iterate through the desired characters, using each one to index into the map. If a given character hasn't been inserted yet, it will read back as 0 – Remy Lebeau Oct 16 '18 at 03:18
1

What you want is to build a simple histogram, and it's pretty easy to do. Since what you're looking at is chars, and there can be 256 possible values of an 8-bit char (in practice your input string probably uses less, but we'll be conservative here because memory is cheap), you'll want to start with an array of 256 ints, all of them initialized to zero. Then iterate over the chars your string, and for each char in your string, use that char-value as an offset into the array(*), and simply increment that item in the array.

When you're done, all that remains is to iterate over the ints in the array and print out the ones that are non-zero, and you're done.

(*) you may want to cast the char to unsigned char before using it as an offset into the array, just to avoid any chance of it being interpreted as a negative array-index, which would result in undefined behavior (this is only an issue if your input string contains ASCII characters 128 and higher, so it may not matter in your case, but it's always good form to make code that does the right thing in all cases if you can)

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
0

As Jeremy frisner said you're building a histogram, but I disagree with the types used.

You'll want to declare your histogram like so:

size_t histogram[sizeof(char)*CHAR_BIT] = {0};

The size_t because you might overflow without it, and you need enough space if it's a nonstandard byte size.

As for printing it out. You should take a look at an ASCII table and examine which values you need to print out.

HSchmale
  • 1,838
  • 2
  • 21
  • 48
  • Per the questioner's code, it appears the size of the input string is guaranteed to be 132 characters or less. Given that, overflowing an `int` is not a problem he will encounter. – Jeremy Friesner Oct 16 '18 at 04:18
0

You could do it by comparing c-strings with other c-strings. But with chars and strings you can get errors like: "const *char cant be compared with strings". So you'll have to compare each c string(array) index with other c string indexes. In this program I use if statements to look for certain vowels. The way it works is that each "string alphabet_letter" is equal to it's respective lowercase and capital letters (for comparison). this is a very redundant way to do it and, if you want to count all total letters, perhaps you should try a different way, but this method doesn't use very complicated methods that require deeper understanding.

using namespace std;

int main(){
int vowel;

string A = "aA";
string E = "eE";
string I = "iI";
string O = "oO";
string U = "uU";
string str;
string str1;

bool userLength = true; 
int restart = 0;

    do{
        cout << "Enter a string." <<endl;
            getline(cin, str);
int VowelA = 0;
int VowelE = 0;
int VowelI = 0;
int VowelO = 0;
int VowelU = 0;

    for(int x = 0; x < 100; x++){

if(restart == 1){
    restart = 0;
    x = 0;
}
if(A[0] == str[x]){
    VowelA = VowelA + 1;
}
if(E[0] == str[x]){
    VowelE = VowelE + 1;
}
if(I[0] == str[x]){
    VowelI = VowelI + 1;
}
if(O[0] == str[x]){
    VowelO = VowelO + 1;    
}
if(U[0] == str[x]){
    VowelU = VowelU + 1;    
}

if(A[1] == str[x]){
    VowelA = VowelA + 1;
}
if(E[1] == str[x]){
    VowelE = VowelE + 1;
}
if(I[1] == str[x]){
    VowelI = VowelI + 1;
}
if(O[1] == str[x]){
    VowelO = VowelO + 1;    
}
if(U[1] == str[x]){
    VowelU = VowelU + 1;    
}
int strL = str.length();
if(x == strL){
    cout << "The original string is: " << str << endl;
cout << "Vowel A: "<< VowelA << endl;
cout << "Vowel E: "<< VowelE << endl;
cout << "Vowel I: "<< VowelI << endl;
cout << "Vowel O: "<< VowelO << endl;
cout << "Vowel U: "<< VowelU << endl;
cout << " " << endl;
}
}

char choice;
cout << "Again? " << endl;

cin >> choice;

if(choice == 'n' || choice == 'N'){userLength = false;}
if(choice == 'y' || choice =='Y')
{
restart = 1;  userLength = true;
cin.clear();
cin.ignore();

}
//cout << "What string?";
//cin.get(str, sizeof(str),'\n');

}while(userLength == true);
}



/*
Sources:


printf help
http://www.cplusplus.com/reference/cstdio/printf/

This helped me with the idea of what's a vowel and whats not.
http://www.cplusplus.com/forum/general/71805/

understanding gets()
https://www.programiz.com/cpp-programming/library-function/cstdio/gets

Very important functional part of my program...Logic behind my if statements, fixed my issues with string comparison
What i needed to do was compare each part of one cstring with another c string
strstr compares two strings to see if they are alike to one another this source includes that idea-> https://www.youtube.com/watch?v=hGrKX0edRFg
so I got the idea: What is one c string was all e's, I could then compare each index for similarities with a c string whos definition was all e's.  
At this point, why not just go back to standard comparison with strings?  But you cant compare const chars to regular chars, so I needed to compare const chars to const chars
hence the idea sparked about the c strings that contained both e and E.
https://stackoverflow.com/questions/18794793/c-comparing-the-index-of-a-string-to-another-string
https://stackoverflow.com/questions/18794793/c-comparing-the-index-of-a-string-to-another-string

Fixed Error with using incremented numbers outside of involved forloop.
https://stackoverflow.com/questions/24117264/error-name-lookup-of-i-changed-for-iso-for-scoping-fpermissive

understanding the use of getline(cin, str_name)
https://stackoverflow.com/questions/5882872/reading-a-full-line-of-input
http://www.cplusplus.com/reference/istream/istream/getline/
http://www.cplusplus.com/forum/beginner/45169/

cin.clear - cin.ignore --fixing issue with cin buffer not accepting new input.
https://stackoverflow.com/questions/46204672/getlinecin-string-not-giving-expected-output


*/
Thomas
  • 2,622
  • 1
  • 9
  • 16