2

I'm trying to increment an array (alphabet[0]) index whenever the letter 'a' appears in the user input, however when I print out alphabet[0] I received the wrong output.

Example problem:

"Enter a string" 

adam //input 

2665453 //printed on screen
2665453
2665453
2665453
2665453

The output I'm attempting to achieve should be the number 2, for the 2 'a's in adam.

Here is my code:

class Counter {

    public:
        string input; //the string used for user input
        int alphabet[26];
        int numbers[10];
    void countcharacters();
    void countnumbers();

    private:
};

void Counter::countcharacters() {
    cout << "Enter a string" <<endl;
    getline(cin, input);

    for(int i=0; i<input.length(); i++) {
        if(input.at(i) == 'a'){
            alphabet[0]++;
        }
    cout << alphabet[0] << endl;
    }
}
3
  • If you just want one number '2' to be printed onto the screen, you're going to want to put that cout statement outside of your for loop. Commented Jul 16, 2013 at 23:12
  • You need to either expand the alphabet array to 52 to account for lower case letters or use std::tolower or std::toupper to convert the letters to the same case. Commented Jul 16, 2013 at 23:13
  • Note: a string can contain non-alphabetical characters, so you should look at std::isalpha to determine if the character is alphabetical. Commented Jul 16, 2013 at 23:15

2 Answers 2

8

The problem is quite simple. Your memory is uninitialized. Your array contains ints that have bad values. In the constructor for your counter class set them all to 0.

You can easily do so using std::fill which is found in the algorithm header. Documentation for it can be found here.

class Counter{

public:
    Counter()
    {
        std::fill(std::begin(alphabet), std::end(alphabet), 0); // C++11
        std::fill(alphabet, alphabet + 10, 0); // c++03
    }

    // The rest of your class goes here
};

The std::begin and std::end templates can be found in the iterator header.

Sign up to request clarification or add additional context in comments.

2 Comments

Correct, most languages initialize values to zero by default, but c languages do not. Your variables starting value would be whatever was left in the memory location used to define the value which ends up giving you a seemingly random value.
Thank you kindly sir, that worked perfectly. I'm quite grateful.
0

Here is also an example that controls the input, and stores every count on the character it counts for:

////////////////////////////
// AlphaNumCounter.h
////////////////////////////


#ifndef ALPHANUMCOUNTER_H
#define ALPHANUMCOUNTER_H
#include "stdafx.h"
#include <vector>
#include <map>

namespace MyStuff
{
const int NOT_VALID_SEARCH_CHAR = -1;

class AlphaNumCounter
{
public:
    AlphaNumCounter();
    AlphaNumCounter(bool bIsCaseSensitive);

    unsigned int CountOccurance(const std::string &haystack, const char &needle);

    // Debug func that print all the occurances of a character on the last CountOccurance call
    void PrintOccurances()
    {
        for( std::map<char, unsigned int>::iterator pIter = m_mapAlphaNumerics.begin(); pIter != m_mapAlphaNumerics.end(); pIter++)
        {
            char c = (*pIter).first;
            int count = (*pIter).second;

            std::cout << "'" << c << "' had '" << count << "' occurances on last count iteration." << std::endl;
        }
    }

private:
    void Init(); // Shared initializer for all ctor's

    std::map<char, unsigned int> m_mapAlphaNumerics; // A map which holds the number of occurances of char (i.e: ['a'][7], if 'a' was found 7 times )
    bool m_bIsCaseSensitive; // Should 'A' be counted as 'a', and vice versa...?
};
}

#endif // ALPHANUMCOUNTER_H

/////////////////////////////////
// AlphaNumCounter.cpp
/////////////////////////////////


#include "stdafx.h"
#include "AlphaNumCounter.h"
#include <algorithm>

using namespace MyStuff;

AlphaNumCounter::AlphaNumCounter() : m_mapAlphaNumerics(), m_bIsCaseSensitive(false)
{
    Init();
}
AlphaNumCounter::AlphaNumCounter(bool bIsCaseSensitive) : m_mapAlphaNumerics(), m_bIsCaseSensitive(bIsCaseSensitive)
{
    Init();
}

void AlphaNumCounter::Init()
{
    // Store lowercase a - z
    for( char i = 'a'; i <= 'z'; i++ )
        m_mapAlphaNumerics[i] = 0;

    // Store uppercase a-z
    for( char i = 'A'; i <= 'Z'; i++ )
        m_mapAlphaNumerics[i] = 0;

    // Store 0 - 9
    for( char i = '0'; i <= '9'; i++ )
        m_mapAlphaNumerics[i] = 0;
}

unsigned int AlphaNumCounter::CountOccurance(const std::string &haystack, const char &needle)
{
    // If neither a-z || A-Z || 0-9 is being searched for, we return a indication of that.
    if(m_mapAlphaNumerics.find(needle) == m_mapAlphaNumerics.end())
        return NOT_VALID_SEARCH_CHAR;

    char ch = needle;
    std::string sz = haystack;


    // If the check is not case sensitive (i.e: A == a), we make sure both params are lowercase for matching.
    if( !m_bIsCaseSensitive ){
        ch = ::tolower(ch);
        std::transform(sz.begin(), sz.end(), sz.begin(), ::tolower);
    }

    // Count occurances of 'ch' in 'sz' ('needle' in 'haystack')
    std::size_t n = std::count(sz.begin(), sz.end(), ch);

    // The occurances of 'needle' must be set to 'n' for this iteration
    m_mapAlphaNumerics[ch] = n;

    // Also set the uppercase val if its case insensitive. Then both 'a' and 'A' would have the same occurance count.
    if( !m_bIsCaseSensitive )
        m_mapAlphaNumerics[::toupper(ch)] = n;

    return n; // Return the count for convenience of usage
}




//////////////////////
// Main.cpp
//////////////////////


using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    MyStuff::AlphaNumCounter aCounter;
    aCounter.PrintOccurances();

    cout << "\n--------------------------------------------------------------\n";
    cout << "Enter a string: " << std::endl;
    string haystack = string();
    getline(cin, haystack);

    cout << "\nNow enter a single alphanumerical character to count, in that string: " << endl;
    char needle;
    cin >> needle;
    cin.clear();
    cin.ignore( numeric_limits<streamsize> ::max(), '\n');

    while( aCounter.CountOccurance(haystack, needle) == MyStuff::NOT_VALID_SEARCH_CHAR )
    {
        cout << "\nI repeat: enter a single *alphanumerical* character to count, in that string: " << endl;
        cin >> needle;
        cin.clear();
        cin.ignore( numeric_limits<streamsize> ::max(), '\n');
    }

    cout << "\n--------------------------------------------------------------\n";
    aCounter.PrintOccurances();

    system("PAUSE");
    return 0;
}

Hope it helps! Regards, Oyvind

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.