i am a new student and i am trying to align the output of my program in neat columns
i have to use an "if" statement to print an asterisk next to numbers divisible by 4.
I have tried using the cout.width, but it is difficult to do this properly. If anyone has a suggestions
i would appreciate it.
thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2007-09-18
>> I have tried using the cout.width, but it is difficult to do this properly.
What does that mean? Why is it difficult? Why don't you post the code you are trying to get to work?
Thanks a lot for your help. This is only the second program I have written. I would not have considered most of this. I appreciate you taking the time.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2007-09-18
I found it easier to see what was happening with your code by setting the fill character to something other than space with "cout.fill('.') ;". This allows you to better understand what ostream::width() does. I then also stepped through the code in the debugger (OK I used VC++ 2005 for that because Dev-C++'s debugger sucks).
The problem with ostream::width() is that it starts from where it last output and not all the values output have the same number of digits. You can use ostream::precision() in conjunction with iomanip::fixed to almost resolve this by forcing all numbers to display the same number of decimal places, but this breaks for number >= 100 because it has an extra digit before the decimal - I imagine that you need the decimal points aligned?
One method would be to format the value to a string using an ostringstream object, and then inspect the string to determine the appropriate ammount of padding from the position of the decimal point. Another method is to use the fact that (int)log10(x) is equal to one less that the number of digits before the decimal point.
Another issue was that you were outputting a newline after the '*'/' ', which was also messing up the formatting, and the 'number' output has one, two or three digits - so that needs a width setting also.
Some unrelated issues:
1) ostream::precision() is persistent; you only need to set it when you want it to change.
2) When you use <cmath> rather than <math.h> it adds overloaded functions for single precision arguments, so passing an int to sqrt() is ambiguous since it could be resolved with eithe float or double precision versions. I am not sure why MinGW/GCC did not complain, but VC++ 2005 did. The solution is to cast:
sqroot = sqrt( double(number) ) ;
3) The following is a possibly more efficient and intuitive method of getting the fourth root:
frthroot = pow( double(number), 0.25 ) ;
4) system() is defined in <cstdlib>, not including it is not necessarily portable - you get away with it becayse it is indirecly included by <iostream>. VC++ 2005 was less forgiving. Using more than one compiler is a good way of finding errors and portability issues.
5) Global variables should be avoided, in your case all your variables were declared globally entirely unnecessarily. Since you only have one function, this is perhaps an academic point, but best not to fall into bad habits.
Any how, consider this for example:
include <cmath>
include <cstdlib>
using namespace std;
int main ()
{
int number ;
double sqroot, frthroot;
i am a new student and i am trying to align the output of my program in neat columns
i have to use an "if" statement to print an asterisk next to numbers divisible by 4.
I have tried using the cout.width, but it is difficult to do this properly. If anyone has a suggestions
i would appreciate it.
thanks
>> I have tried using the cout.width, but it is difficult to do this properly.
What does that mean? Why is it difficult? Why don't you post the code you are trying to get to work?
Have you considered simply using '\t'?
cout << "col1" << "\tcol2" << "\tcol3" << endl ;
cout << value1 << '\t' << value2 << '\t' << value3 << endl ;
If your problem is that printing the * causes the value to be misaligned, simply print a space for all other values:
if( x % 4 == 0 )
{
cout << '*' ;
}
else
{
cout << ' ' ;
}
cout << x ;
Frankly it is not at all clear what it is that you want to achieve - so I'll stop guessing!
Clifford
Thanks a lot for your help. This is only the second program I have written. I would not have considered most of this. I appreciate you taking the time.
This is my program. The real problem is that the asterisk ends up running into the next column, instead of having a column of its own.
include <iostream>
include <cmath>
using namespace std;
int number ;
double sqroot, frthroot;
int main ()
{
}
system("pause");
return 0;
}
I found it easier to see what was happening with your code by setting the fill character to something other than space with "cout.fill('.') ;". This allows you to better understand what ostream::width() does. I then also stepped through the code in the debugger (OK I used VC++ 2005 for that because Dev-C++'s debugger sucks).
The problem with ostream::width() is that it starts from where it last output and not all the values output have the same number of digits. You can use ostream::precision() in conjunction with iomanip::fixed to almost resolve this by forcing all numbers to display the same number of decimal places, but this breaks for number >= 100 because it has an extra digit before the decimal - I imagine that you need the decimal points aligned?
One method would be to format the value to a string using an ostringstream object, and then inspect the string to determine the appropriate ammount of padding from the position of the decimal point. Another method is to use the fact that (int)log10(x) is equal to one less that the number of digits before the decimal point.
Another issue was that you were outputting a newline after the '*'/' ', which was also messing up the formatting, and the 'number' output has one, two or three digits - so that needs a width setting also.
Some unrelated issues:
1) ostream::precision() is persistent; you only need to set it when you want it to change.
2) When you use <cmath> rather than <math.h> it adds overloaded functions for single precision arguments, so passing an int to sqrt() is ambiguous since it could be resolved with eithe float or double precision versions. I am not sure why MinGW/GCC did not complain, but VC++ 2005 did. The solution is to cast:
sqroot = sqrt( double(number) ) ;
3) The following is a possibly more efficient and intuitive method of getting the fourth root:
frthroot = pow( double(number), 0.25 ) ;
4) system() is defined in <cstdlib>, not including it is not necessarily portable - you get away with it becayse it is indirecly included by <iostream>. VC++ 2005 was less forgiving. Using more than one compiler is a good way of finding errors and portability issues.
5) Global variables should be avoided, in your case all your variables were declared globally entirely unnecessarily. Since you only have one function, this is perhaps an academic point, but best not to fall into bad habits.
Any how, consider this for example:
include <cmath>
include <cstdlib>
using namespace std;
int main ()
{
int number ;
double sqroot, frthroot;
}
Clifford
Clifford
... PS: 6) I used the ternary operator in place of the if/else - no reason other than succinctness.
Clifford
... oh and your were right BTW - is is not exactly obvious! ;)