hey all,,,

i've been trying to make my own setw function that will do the same jop of setw,, this is my first year in college i study CIS in Jordan,,,

so, i made this code but6 i still have problims with float numbers, it seems like this code work on int numbers,, as u can see i've used my function in an example,,,,

plz help :D

#include<iostream.h>
#include<math.h>

    void myset( int w, float num ){
    int n=0;
    float num1 = fabs(num);
    while (num1 >= 1){
        num1/=10;
        n++;
    }

    for ( int i =0; i < w-n; i++){

    cout<< "0";
    }
    cout<<num<<endl;
}// end of the function 


main ()
{
    int w;
    float num;
    cout <<"enter the number"<<endl;
    cin >>num;
    cout<<"enter the number of the spaces"<<endl;
    cin >> w;

    myset(w, num);


}

Dani AI

Generated

Short answer: the tricky parts are controlling the displayed fractional digits (precision), handling rounding that can carry into the integer part, and treating the sign. was right — you must count digits after the point as well — and 's idea (read as a string and parse) is perfectly valid. If you want a compact, predictable formatter that lines up decimals you can instead split the number into integer and fractional parts yourself, round the fraction to the requested precision, build the textual parts, then pad spaces so the decimal point appears in the same column for every value.

The following is a small, self-contained formatter (different approach than the ostringstream-only example posted by ). It returns a string whose decimal point is placed at column dppos and whose total width is at least width. It handles negative values and rounding that carries into the integer part.

#include <sstream>
#include <iomanip>
#include <cmath>
#include <string>

std::string alignDecimal(double x, size_t dppos = 8, size_t width = 0, int prec = 6) {
    bool neg = x < 0.0;
    double ax = std::fabs(x);
    long long ip = static_cast<long long>(ax);
    double frac = ax - ip;
    long long mul = 1;
    for(int i=0;i<prec;i++) mul *= 10;
    long long fi = static_cast<long long>(frac * mul + 0.5); // rounded
    if (fi >= mul) { fi = 0; ++ip; } // carry from rounding
    std::ostringstream oss;
    if (neg) oss << '-';
    oss << ip;
    std::string s = oss.str();
    if (prec > 0) {
        std::ostringstream fss;
        fss << '.' << std::setw(prec) << std::setfill('0') << fi;
        s += fss.str();
    }
    if (s.size() < dppos + (prec>0?0:0) && s.find('.')==std::string::npos) ; // keep simple
    if (s.size() < width && dppos > 0) {
        size_t decIndex = (neg ? s.find_first_of("0123456789") : 0) + (s.find('.')==std::string::npos ? s.size() : s.find('.'));
        if (decIndex < dppos) s = std::string(dppos - decIndex, ' ') + s;
    }
    if (s.size() < width) s += std::string(width - s.size(), ' ');
    return s;
}

Notes and pitfalls

  • Rounding can bump the integer part (handled above). Test edge cases like 0.9995 with your precision.
  • NaN, INF, very large numbers or scientific notation require extra handling.
  • Locale can change the decimal separator ('.'); this code uses '.' explicitly.
  • If you want a true stream manipulator (so you can do cout << mysetw(8) << x;), wrap formatting in a small object and overload operator<< — that's a useful next step and what hinted at.

Recommended Answers

All 8 Replies

->First: Please post using code tags!
->Second: You have to know how to write manipulators :)

What it looks like you're doing is displaying floats so that they will line up at the decimal point. Your loop to count digits is only counting the whole number portion.

If you're trying to mimic the setw( )manipulator, you're going to have to know how many digits fall after the decimal as well. For this, you need to know the precision in use, then subtract the number of digits in the whole number portion. Then there's the rounding of float values when displayed, depending on precision. Starting to sound pretty complex.

thx everyone for ur help, and i'm really srry that i didnt include any comments on the program, i have just made it and i post it fast as i can,,,,

the main problim is that code can just count clumns for int number before the point ".",,, so i want to ask if there is anything in c++ can separate the numbers after the point, so that i can do the same process on the numbers after the point as integers numbers ... thx

you could recive the numbers as strings then parsing through them find the decimal point then you will know how many digits are before the decimal point and how many are after for each number then its just a matter of displaying them as you want. maybe that will work for you but it is alot of coding and checking.

this is my code with the comments,,,,

#include<iostream.h>
#include<math.h>

    void myset( int , float  );// declare the function 




main ()
{
int w;
float num;
cout <<"enter the number"<<endl;
cin >>num;
cout<<"enter the number of the spaces"<<endl;
cin >> w;

myset(w, num);


}


    void myset( int w, float num ){ // inlization the function 

    int n=0;

    float num1 = fabs(num); // using fabs if the number < 0 
    while (num1 >= 1){
        num1/=10;// for example if the number is 100 it will be 10 then 1,, everyloop 
        n++;// every loop the num will be divided, that's how the program will know if the number is from tens or handrerds or thouthands .... etc
    }

    for ( int i =0; i < w-n; i++){

    cout<< " ";//print the spaces
    }
    cout<<num;

return;

}
commented: Didn't I say to post using code tags? +0

NathanOliver,,, can u tell me exatly how to do that ???

It seems that you can't write STL stream manipulator at this moment. Next time try to formulate the true problem, not your ideas about possible (incorrect) solutions of undefined problems.

Try this:

template<typename Number>
std::string lineUp(Number x, size_t prec, size_t dppos, size_t w = 0)
{
    std::ostringstream os;
    os << std::fixed << std::setprecision(prec) << x;
    size_t pos = os.str().find('.');
    if (pos == std::string::npos) {
        pos = os.str().size();
    }
    std::string s;
    if (pos < dppos)
        s.resize(dppos-pos,' ');
    s += os.str();
    if (w > 0 && s.size() < w)
        s.resize(w,' ');
    return s;
}
using std::cout;
int main()
{
    std::string s;
    s = lineUp(3.14159265358,6,8,16);
    cout << '>' << s << "<\n";
    cout << " 0123456789abcdef\n";
    s = lineUp(2009,6,8,16);
    cout << '>' << s << "<\n";
    cout << " 0123456789abcdef\n";
    s = lineUp(3.14f,6,8,16);
    cout << '>' << s << "<\n";
    cout << " 0123456789abcdef\n";
    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.