-2

I'm a beginner on programming. I'm coding a school assignment and its asking me to add commas to a string using recursion. I have most of it done but when I input a number greater than a million it doesn't add a comma before the first digit. This is what i have so far:

// commas - Convert a number (n) into a string, with commas
string commas(int n) {

    ostringstream converted;
    converted << n;

    string number = converted.str();

    int size = number.length();

    if (size < 4 )
    {
    return number;
    }
    if (size >= 4 )
    {
        return number.substr(0, number.size() - 3) + "," + number.substr(number.size() - 3, number.length());
    }
}   

Any help would be greatly appreciated!

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
user3363821
  • 1
  • 1
  • 1

3 Answers3

2

The algorithm is fairly simple. It is very similar to your solution except I added the part necessary for recursion. To understand how it works, remove tack_on. Here is example output:

1
10
100

These are the first groups that are returned when the terminating condition is reached (s.size() < 4). Then the rest of the groups are prefixed with a comma and "tacked on". The entire string is built using recursion. This is important because if you left number.substr(0, number.size() - 3) in, your output would look like this:

11,000
1010,000
100100,000
11,0001000,000

I use std::to_string which is C++11:

#include <iostream>

std::string addCommas(int n)
{
    std::string s = std::to_string(n);
    if (s.size() < 4) return s;
    else
    {
        std::string tack_on = "," + s.substr(s.size() - 3, s.size());
        return addCommas(n / 1000) + tack_on;
    }
}

You only need to make minimal changes for the C++03/stringstream version:

#include <sstream>

std::ostringstream oss;

std::string addCommas(int n)
{
    oss.str(""); // to avoid std::bad_alloc
    oss << n;
    std::string s = oss.str();
    // etc
}

Testing:

int main()
{
    std::cout << addCommas(1) << "\n";
    std::cout << addCommas(10) << "\n";
    std::cout << addCommas(100) << "\n";
    std::cout << addCommas(1000) << "\n";
    std::cout << addCommas(10000) << "\n";
    std::cout << addCommas(100000) << "\n";
    std::cout << addCommas(1000000) << "\n";
    return 0;
}

Output:

1
10
100
1,000
10,000
100,000
1,000,000
1

I think this one is a bit simpler and easier to follow:

std::string commas(int n)
{
    std::string s = std::to_string(n%1000);
    if ((n/1000) == 0) return s;
    else
    {
        // Add zeros if required
        while(s.size() < 3)
        {
            s = "0" + s;
        }
        return commas(n / 1000) + "," + s;
    }
}
uncletall
  • 6,609
  • 1
  • 27
  • 52
0

an alternative approach without recursion:

class Grouping3 : public std::numpunct< char >
{
protected:
    std::string do_grouping() const { return "\003"; }
};

std::string commas( int n )
{
    std::ostringstream converted;
    converted.imbue( std::locale( converted.getloc(), new Grouping3 ) );
    converted << n;
    return converted.str();
}

will need #include <locale> in some environments

A possible solution for the assignment could be:

std::string commas( std::string&& str )
{
    return str.length() > 3?
        commas( str.substr( 0, str.length()-3 ) ) + "," + str.substr( str.length()-3 ):
        str;
}
std::string commas( int n )
{
    std::ostringstream converted;
    converted << n;
    return commas( converted.str() );
}
cpp-progger
  • 406
  • 3
  • 6