HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppModerate

Converting an integer into the written form

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thewrittenintoformconvertinginteger

Problem

For my homework assignment I have to create a class which converts an integer between 0 and 9999 into the written form. For example, 713 would be written as "seven hundred thirteen."

I wrote a few variations and I think I found the best approach. However, I was wondering if anyone had a moment to comment on my approach. Maybe point out subtle things I might not be taking advantage of. Things like that.

I'll list just the important excerpts from the .cpp and .h files.

The following are all static members of the Numbers class:

const char* Numbers::lessThan20[] = {
  "zero",     "one",      "two",      "three",   "four",    "five",
  "six",      "seven",    "eight",    "nine",    "ten",     "eleven",
  "twelve",   "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
  "eighteen", "nineteen"
};
const char* Numbers::over19[] = {
  "",       "",      "twenty", "thirty", "fourty", "fifty", "sixty", "seventy",
  "eighty", "ninety"
};
const char* Numbers::hundred  = "hundred";
const char* Numbers::thousand = "thousand";


And this is my function to convert the number into a string:

std::string Numbers::print() const
{
  std::string text;
  int whole, remainder;

  remainder = this->number; //  0)
    text = text + lessThan20[whole] + " " + thousand + " ";

  whole = remainder / 100;
  remainder %= 100;

  if (whole > 0)
    text = text + lessThan20[whole] + " " + hundred + " ";

  if (remainder > 19)
  {
    whole = remainder / 10;
    remainder %= 10;
    text = text + over19[whole];
    if (remainder > 0)
      text = text + "-" + lessThan20[remainder];

  }
  else if (remainder > 0)
    text = text + lessThan20[remainder];

  return text;
}

Solution

Use STL Containers

Prefer using std::array (if your compiler supports it or) std::vector instead of raw arrays. Also, I would recommend using std::string instead raw character pointers.

const std::array Numbers::lessThan20 = {
  "zero",     "one",      "two",      "three",   "four",    "five",
  "six",      "seven",    "eight",    "nine",    "ten",     "eleven",
  "twelve",   "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
  "eighteen", "nineteen"
};
const std::array Numbers::over19 = {
  "",       "",      "twenty", "thirty", "fourty", "fifty", "sixty", "seventy",
  "eighty", "ninety"
};
const std::string Numbers::hundred  = "hundred";
const std::string Numbers::thousand = "thousand";


Edge Cases

Currently there is no handling for edge cases. If the number is 0 it will return an empty string instead of "zero". Numbers greater than or equal to 20000 will cause an out of range access. Therefore, numbers too large need to be properly handled. These cases can checked at the beginning of the function.

A couple other minor points: I would remove the line int whole, remainder and declare the variables when they are initialized. This will reduce the variables' scope and does not leave them initialized. Also, prefer text += ... over text = text + .... It's more clear that you are appending and less typing. Lastly, I would recommend to always use curly braces even when there is only one statement.

Here is your function with my recommendations:

std::string Numbers::print() const
{
  int remainder = this->number; // = 20000)
  {
    // handle this case
  }

  int whole = remainder / 1000;
  remainder %= 1000;

  std::string text;
  if (whole > 0)
  {
    text += lessThan20[whole] + " " + thousand + " ";
  }

  whole = remainder / 100;
  remainder %= 100;

  if (whole > 0)
  {
    text = text + lessThan20[whole] + " " + hundred + " ";
  }

  if (remainder > 19)
  {
    whole = remainder / 10;
    remainder %= 10;
    text = text + over19[whole];
    if (remainder > 0)
    {
      text = text + "-" + lessThan20[remainder];
    }
  }
  else if (remainder > 0)
  {
    text = text + lessThan20[remainder];
  }
  return text;
}

Code Snippets

const std::array<std::string, 20> Numbers::lessThan20 = {
  "zero",     "one",      "two",      "three",   "four",    "five",
  "six",      "seven",    "eight",    "nine",    "ten",     "eleven",
  "twelve",   "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
  "eighteen", "nineteen"
};
const std::array<std::string, 10> Numbers::over19 = {
  "",       "",      "twenty", "thirty", "fourty", "fifty", "sixty", "seventy",
  "eighty", "ninety"
};
const std::string Numbers::hundred  = "hundred";
const std::string Numbers::thousand = "thousand";
std::string Numbers::print() const
{
  int remainder = this->number; // <- number is a member variable of the Numbers class
  if(remainder == 0)
  {
    return lessThan20[0];
  }

  if(remainder >= 20000)
  {
    // handle this case
  }


  int whole = remainder / 1000;
  remainder %= 1000;

  std::string text;
  if (whole > 0)
  {
    text += lessThan20[whole] + " " + thousand + " ";
  }


  whole = remainder / 100;
  remainder %= 100;


  if (whole > 0)
  {
    text = text + lessThan20[whole] + " " + hundred + " ";
  }

  if (remainder > 19)
  {
    whole = remainder / 10;
    remainder %= 10;
    text = text + over19[whole];
    if (remainder > 0)
    {
      text = text + "-" + lessThan20[remainder];
    }
  }
  else if (remainder > 0)
  {
    text = text + lessThan20[remainder];
  }
  return text;
}

Context

StackExchange Code Review Q#6780, answer score: 10

Revisions (0)

No revisions yet.