Erik Sandoval
Erik Sandoval

Reputation: 13

How to add all Ascii values between two chars?

My assignment is to:

Write a function called sumConsonants that will take as arguments two upper case letters. Your function should return a sum of all the ascii values of the consonants between the starting character and the ending character. Your main function should pass two values to the function and output the sum of all the consonant character values including the first and the last

this is what I have so far:

#include <iostream>
using namespace std;

int sumConsonants(char, char);

int main()
{
  char char1, char2;
  cout << "Enter two upper case chars" << endl;
  cin >> char1 >> char2;

  cout << "The sum of the consonants between the two chars is " << sumConsonants(char1, char2) << endl;


  return 0;
}

int sumConsonants(char first, char last)
{
  char f = first;
  char l = last;

  int first1 = static_cast<int>(f);
  int last2 = static_cast<int>(l);

  return first1 + last2;
}

not really sure how to make it so it adds all the values between the char inputs

Upvotes: 1

Views: 1328

Answers (3)

Tom Blodget
Tom Blodget

Reputation: 20772

This should get you started. You seemed to be stuck on how to loop on char values. for supports that because char is an integer type. In ASCII and all derivative character sets, the Basic Latin uppercase letters are sequential and in the order of the English alphabet so you can iterate over a range of them and use subtraction to determine how far one is from 'A'—that forms a natural mapping: A ↔ 0, B ↔ 1,… Z ↔ 25.

I had some questions about the meaning of "between the starting character and the ending character" so I wrote down what I thought the answers should be. For example: What's between B and B? (See BB_should_equal_B below.) This is in the form of "unit tests".

Unit testing is a technique that is taught way too late. You don't have to understand much to get started. I used the Google Test framework. If you have trouble building the library and using the include files in your project, perhaps someone like a TA can help you. (They might even thank you for showing them unit testing.)

In any case, you can see how it helps define what your goals are and gives you a place to write down some test values. Other than the funky syntax, a test has:

  • a name that describes the requirement.
  • a test framework assert that checks the actual value vs the expected (correct) value.

.

#include  <cassert>
#include "gtest/gtest.h"

using namespace std;

int sumConsonants(char first, char last);

class CharSumTestFixture : public ::testing::Test {
};


TEST_F(CharSumTestFixture, AA_should_equal_zero) {
    ASSERT_EQ(sumConsonants('A', 'A'), 0);
}

TEST_F(CharSumTestFixture, BB_should_equal_B) {
    ASSERT_EQ(sumConsonants('B', 'B'), 'B');
}

TEST_F(CharSumTestFixture, BCD_should_equal_B_plus_C_plus_D) {
    ASSERT_EQ(sumConsonants('B', 'D'), 'B' + 'C' + 'D');
}

TEST_F(CharSumTestFixture, AE_should_equal_B_plus_C_plus_D) {
    ASSERT_EQ(sumConsonants('A', 'E'), 'B' + 'C' + 'D');
}

TEST_F(CharSumTestFixture, AZ_should_equal_A_through_Z_minus_A_minus_E_minus_I_minus_O_minus_U) {
    auto n = 'Z' - 'A' + 1;
    auto gauss = n * (n + 1) / 2;
    auto offset = 'A' - 1;
    auto sumAZ = gauss + n * offset;
    ASSERT_EQ(sumConsonants('A', 'Z'), sumAZ - 'A' - 'E' - 'I' - 'O' - 'U');
}


int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

int sumConsonants(char first, char last)
{
    // Assertions are used to communicate, during development and maintenace, already accepted pre-conditions. 
    // They are not for handling cases where those conditions do not exist.
    assert((first >= 'A') && (first <= 'Z'));
    assert((last >= 'A') && (last <= 'Z'));

    int sum = 0;
    for (auto letter = first; letter <= last; letter++)
    {
        sum += letter; // BUG must not add non-consonants
    }
    return sum;
}

Failing Test Cases

Upvotes: 0

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

char f = first;
char l = last;

int first1 = static_cast<int>(f);
int last2 = static_cast<int>(l);

You don't need to duplicate the input or cast to integer.

Casting can sometimes hide errors. Don't cast unless the compiler complains (set the compiler's warning level to 4 or maximum). And then think about what the cast is doing before applying it.

char always fits in to int, so you can safely add up the integer values of characters. Example:

int sumConsonants(char first, char last)
{
    const std::string vowels = "AEIOU";
    int result = 0;
    for (char ch = first; ch <= last; ch++)
        if (vowels.find(ch) == std::string::npos)
            result += ch;
    return result;
}

In your assignment you are probably not allowed to use std::string, so use const char *vowels = "AEIOU" and write your own find function.

Upvotes: 0

UKMonkey
UKMonkey

Reputation: 6983

What you're looking for is characters in the range A-Z (although this can be asserted, since it's defined to be the input) - but NOT AEIOU

If you don't know what I mean by "asserted" - then please look up "c++ assert".

After that, a for loop going from start to end checking to see if each step is (not) one of those chars should do the job.

Upvotes: 1

Related Questions