Search code examples
c++arraysstringif-statementgetline

c++ - string confrontation issue


I have to create a little program in C++, expecting a string in input and outputting its content in letters (How many As it's got, and so on).

I'm doing this by creating an integer array of 26 blocks, and confronting with a for cycle my string with the string "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and the lower-case one. If a correspondence is found with index i, the i-th array block's value is incremented by one, and the for cycle is broken.

However, I have a little problem: if a character not present in the alphabet string is inserted (like a whitespace, or an apostrophe), it is counted as a correspondence for i=0 (letter A). However, if I include that character too in my alphabet string, and cycle through it with my for, the problem does not occur.

This is my .cc file (functions implementation)

#include "08.Count.h"
#include <string>
#include <iostream>

using namespace std;

int chartoint (char a)  {
//Converts an alphabetic character to its corresponding position in the alphabet (as an integer)
    string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string alphabet2 = "abcdefghijklmnopqrstuvwxyz";

    for (int i=0; i<26; i++)

        if ((a==alphabet[i])||(a==alphabet2[i]))    {
        //check if the char corresponds to the upper-case OR lower-case i-th letter of the alphabet
            return i;
            //when we find a correspondence, we output the point at where we've found it
            break;
            //waste of time continuing cycling if the correspondence is already found
            }

}

void list (string word) {
//Outputs the alphabetic distribution of the input string
    int array[26];
    //array to store the correspondence data for each alphabet letter
    for (int i=0; i<26; i++)

        array[i]=0; //Initialize

    for (int i=0; word[i]!='\0'; i++)

        array[chartoint(word[i])]++;
        //chartoint(word[i]) outputs the position of the alphabet the i-th character of the string word corresponds. We increment the value of that position in the array by one
    string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    for (int i=0; i<26; i++)

        if (array[i]!=0) 

            cout << array[i] << "  " << alphabet [i] << ", ";
    //we output the distribution in letters, but only for the letters that are found at least one time
}

And this is my main program

#include <iostream>
#include <string>
#include "08.Count.h"

using namespace std;

int main() 

{

    string word;

    cout << "Insert phrase" << endl;

    getline(cin, word);
    //To avoid the input string being terminated by a whitespace
    cout << "The phrase " << word << " contains:" << endl;

    list (word);

    cout << endl;

}

Solution

  • In your chartoint function there is only one return inside loop. There are no measures to handle when a character is not an alphabet. So in that case the return value is undefined(for you it is returned as 0)

    So change the function chartoint as

    int chartoint (char a)  {
    
    string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string alphabet2 = "abcdefghijklmnopqrstuvwxyz";
    
    for (int i=0; i<26; i++)
    
        if ((a==alphabet[i])||(a==alphabet2[i]))    {
             return i;
            }
     return -1; // <------ indicates a is not an alphabet
    }
    

    Change the function list as

    void list (string word) {
    
    int array[26],index;
    for (int i=0; i<26; i++)
        array[i]=0; //Initialize
    
    for (int i=0; word[i]!='\0'; i++)
    {
      index = chartoint(word[i]); 
      if(index!=-1) // <--- Check returned index
        array[index]++;
    } 
    string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    for (int i=0; i<26; i++)
        if (array[i]!=0) 
            cout << array[i] << "  " << alphabet [i] << ", ";
    
    }
    

    So if returned index is not -1 increment the corresponding character count by 1. Else ignore it because it is not an alphabet.