Hi guys,

Im working through accelerated c++ book and in chapter 4 ex 2 i had to build a program that displayed the square of ints (i) 1->100 inclusive using setw() to align the results.
this i did ok and it works fine like 3 lines of code.

However in ex4.3 it says
"rewrite the program to be more robust in the faces of changes that allow i to grow without adjusting the setw arguments"

To do this i have an idea but i dont know if its what the autor means or something else.

Idea: get the largest size of i permissable calculate the width it would require to be displayed for the number itself and the square and store this in a var. then loop through 1->i and print results.

Why i think thats wrong is: does that really meet what the question asks for as i can grow but we have to know the maximum value as before. is simply asjusting the argument to setw based on an initial calculation like this really all the solution would need to solve the question correctly?

I hope this does not seem like too daft a question and its just me overthinksing things

Thanks

Edited 6 Years Ago by Kanoisa: n/a

You are exactly right about the point of the question. The question is there in order to encourage readers to stop thinking about data formats in terms of absolute sizes, and to try to write programs with output that conforms to the data being displayed.

Yes, that should be an appropriate solution.
The task says that the setw argument shouldn't need to be changed manually when i grows - and your solution does just that.

Okay thanks, i think the wording threw me a bit so i confused myself a little in what i had to do. thanks for the help :)

Sorry to bug you guys again,..

would you tell me what you think of how i coded this solution? if you think its ok? (bearing in mind we have not covered classes templates or any advanced stuff just manipulators and stl really.)

my code as follows

// ex4.3.cpp : Defines the entry point for the console application.
// builds on ex4.2 this version auto compensates for the maximum width of a field and
// then uses setw to pad all the values

#include "stdafx.h"


using std::cout;	using std::endl;	using std::setw;	
using std::cin;		using std::string;

int getFieldWidth(const int& value);

int _tmain(int argc, _TCHAR* argv[])
{
	std::string userIn;
	
	cout<<"Ex4.3 displays the square of ints from 1->i (specified by user)."<<endl;
	cout<<"Enter the maximum size for i: ";
	cin>>userIn;//get user input

	int loopLimit = atoi(userIn.c_str());//get the numberEntered
	int sizei = getFieldWidth(loopLimit); //get the width of the maximum number
	int sizeii = getFieldWidth(loopLimit*loopLimit); //get the width of the maximum number squared
	
	loopLimit++; //increment to include the number the user typed in
	for(int x = 1; x<loopLimit; x++)//loops from 1->100
	{
		//display results (calculation done in cout)
		//cout<<"Number: "<<x<<" Square: "<<x*x<<endl; //with no setw()
		//cout<<"Number: "<<setw(3)<<x<<" Square: "<<x*x<<endl; //with only first num setw
		cout<<"Number: "<<setw(sizei)<<x<<" Square: "<<setw(sizeii)<<x*x<<endl;
	}

	cin.ignore();
	cin.get();//get a char so i can see the output
	return 0;
}

//sub fn to convert int to string
inline std::string toString(const int &i)
{
	std::stringstream ss;
	ss << i;
	return ss.str();
}

//get size fn
int getFieldWidth(const int& value)
{
	//get length of string
	return(toString(value).length());
}

thanks again :)

It seems quite alright to me! One tip:

//THIS:
cin>>userIn;//get user input

int loopLimit = atoi(userIn.c_str());//get the numberEntered

//COULD BE JUST THIS:
int loopLimit;
cin>>loopLimit;//get user input

Indeed it could,.... i took it into a string first so i could get the length,... but it didnt work so i made a function to fix that and then didnt use it properly,... good find :) thanks

Some suggestions for improvement:

1. No point importing every element manually from the std namespace. An "using namespace std;" does the trick. While you shouldn't just go and import every namespace you find (that would defeat the purpose of namespaces), it's fine for the std namespace. Library designers can generally be expected to avoid clashes with the C++ standard library and this works well in practice - you'll rarely (if ever) encounter problems with other libraries.

2. Where are all the headers? Are you including them in stdafx.h?

3. No atoi! stringstream can be used here for conversion as well - but that is not even necessary. You can read an int directly from cin.

4. Instead of incrementing loopLimit, you can just use x<=loopLimit as the condition in the for loop.

5. There's no point in passing simple types like int/float/pointers etc. by reference. This is just more typing work and does not improve performance (or can hurt it, when no inlining can be performed). Constant references should be used for types that are rather expensive to copy in comparison (e.g. string) and for uncopyable types.

Edited 6 Years Ago by Aranarth: n/a

thanks aranarth in response

1 - was just following suit of the book but i agree with your point.
2 - yes
3 - yeah it was a mess i didnt need to make and i did end up fixing it with string streams to get the strings i needed
4 - i know about that but its a personal thing i just dont like <= i dont know where my opinion on that came from i just dont like it. but again a valid point
5 - fair comment but again i was sticking with the book and being somewhat robotic in that he says const where possible if vars wont change during thier lifetime, and i dont know why i passed by refrence it does seem a tad pointless but you bring an interesting point ,.. can passing by refrence affect the functions ability to be inline? iv never heard of that before (admitting i havent really covered inline just knew its meant to speed up a fucntion by pasting its code where the fucntion should be and fixing up the inputed var refrences in the function to those passed)

thanks for your feedback ill keep it in mind in future work and hopefully get that step closer to feeling confident enough to call myself a "descent" c++ programmer :)

The book recommends against "using namespace std;" because if you use it, and happen to define a name that clashes with a name in the standard library, you wind up with ambiguity problems.

Moreover, because C++ implementations are permitted to extend the standard library by defining their own names (and will surely do so even if they're not permitted), the practical effect of saying "using namespace std;" is that you do not know whether your program will work on a new implementation until you try it.

This question has already been answered. Start a new discussion instead.