Comma Formatting for numbers in C++

前端 未结 5 783
北海茫月
北海茫月 2020-12-17 05:30

I\'m needing help in adding commas to the number the user enters, some guidance or help would be appreciated. So far I have it where i store the first three digits and the l

相关标签:
5条回答
  • 2020-12-17 05:45

    You could do this:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    string commify(unsigned long long n)
    {
      string s;
      int cnt = 0;
      do
      {
        s.insert(0, 1, char('0' + n % 10));
        n /= 10;
        if (++cnt == 3 && n)
        {
          s.insert(0, 1, ',');
          cnt = 0;
        }
      } while (n);
      return s;
    }
    
    int main()
    {
      cout << commify(0) << endl;
      cout << commify(1) << endl;
      cout << commify(999) << endl;
      cout << commify(1000) << endl;
      cout << commify(1000000) << endl;
      cout << commify(1234567890ULL) << endl;
      return 0;
    }
    

    Output (ideone):

    0
    1
    999
    1,000
    1,000,000
    1,234,567,890
    
    0 讨论(0)
  • 2020-12-17 05:52

    EDIT: I have two solutions. first without playing with numbers (recommended) and second (division). first solution is:

    #include <cstdlib>
    #include <iostream>
    #include <locale>
    #include <string>
    using namespace std;
    
    struct my_facet : public std::numpunct<char>{
            explicit my_facet(size_t refs = 0) : std::numpunct<char>(refs) {}
            virtual char do_thousands_sep() const { return ','; }
            virtual std::string do_grouping() const { return "\003"; }
    };
    
    /*
     * 
     */
    int main(int argc, char** argv) {
    
        cout<<"before. number 5000000: "<<5000000<<endl;
    
        std::locale global;
        std::locale withgroupings(global, new my_facet);
        std::locale was = std::cout.imbue(withgroupings);
    
        cout<<"after. number 5000000: "<<5000000<<endl;
    
        std::cout.imbue(was);
    
        cout<<"and again as before. number 5000000: "<<5000000<<endl;
    
        return 0;
    }
    

    before. number 5000000: 5000000
    after. number 5000000: 5,000,000

    and again as before. number 5000000: 5000000

    RUN SUCCESSFUL (total time: 54ms)

    and second (not recommended) is :

    double f = 23.43;
    std::string f_str = std::to_string(f);
    

    or this

    int a = 1;
    stringstream ss;
    ss << a;
    string str = ss.str();
    

    Then you can use string::substr() string::find() string::find_first_of() and similar methods to modify and format your string.
    a similar topic


    If you really want (have to) divide: (I think my version is cleaner & more efficient than the others)

    unsigned long long userInput;
        std::stringstream ss,s0;
        std::string nr;
            std::cout << "Enter a long long number: " << std::endl;
            std::cin >> userInput;
            int input=userInput;
            int digits;
    
            while(input>999){
                input=input/1000;
                digits=userInput-input*1000;
                int mdigits=digits;
                while(mdigits<100){s0<<"0";mdigits*=10;}
                std::string s=ss.str();
                ss.str("");
                ss<<","<<s0.str()<<digits<<s;
                userInput=input;
                s0.str("");
            }
    
            std::string sf=ss.str();
            ss.str("");
            ss<<input<<sf;
    
            std::cout << "Your Number: " << userInput << ";" << digits <<";"<<ss.str()<<std::endl;
    

    Enter a long long number: 12345678 Your Number: 12;345;12,345,678

    0 讨论(0)
  • 2020-12-17 06:01

    Is this what you need? The locale will do this for you correctly.

    #include <iostream>
    using namespace std;
    
    int main ( int argc, char * argv[] ) 
    {
      unsigned long long userInput;
      int fthreeDigit;
      cout << "Enter a long long number: " << endl;
      cin >> userInput;
      std::cout.imbue(std::locale(""));
      std::cout << userInput << std::endl;
    
      return 0;
    }
    
    0 讨论(0)
  • 2020-12-17 06:04

    Here is the brute force but may be easiest to understand way to get every thousand digits with the help of a vector.

    #include<iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    int main ( int argc, char * argv[] ) 
    {
        long long userInput;
        int fthreeDigit;
    
       cout << "Enter a long long number: " << endl;
       cin >> userInput;
       vector <int> res;  //use vector to store every 3 digits
       while (userInput !=0)
       {
         fthreeDigit = userInput %1000;
         res.push_back(fthreeDigit);
         userInput = userInput / 1000 ;
       }
    
       std::reverse(res.begin(), res.end());
       for (size_t i = 0; i < res.size()-1; ++i)
       {
         if (res[i] ==0)
         {
            cout << "000"<<",";
         }
         else
         {
           cout << res[i] << ",";
         }
       }
    
       if (res[res.size()-1] == 0)
       {
           cout << "000";
       }
       else{
           cout << res[res.size()-1];
       }
       cout <<endl;
       cin.get();
       return 0;
    }
    

    I tested this code with the following case:

    Input: 123456 Output: 123,456
    Input: 12     Output: 12
    Input: 12345  Output: 12,345
    Input: 1234567 Output: 1,234,567
    Input: 123456789 Output: 123,456,789
    Input: 12345678 Output: 12,345,678
    

    I guess this is what you want according to your response to comments.

    0 讨论(0)
  • 2020-12-17 06:08
    // Accepts a long number, returns a comma formatted string
    CString num_with_commas(long lnumber)
    {
        CString num;
        num.Format(%d",lnumber);
        if(num.GetLength() > 3) {num.Insert(num.GetLength()-3, ',');}
        if(num.GetLength() > 7) { num.Insert(num.GetLength()-7, ','); }
        if (num.GetLength() > 12) { num.Insert(num.GetLength()-12, ','); }
        return(num);
    }
    
    0 讨论(0)
提交回复
热议问题