StuXYZ 731 Practically a Master Poster

Any online reference to priority_queue
http://www.cplusplus.com/reference/stl/priority_queue/ and the include show that the class takes a templated less functor and a default typebase.

So: (without using default template parameters we have):

#include <iostream>
#include <vector>
#include <queue>

int main ()
{
  std::priority_queue<int,std::vector<int>,std::less<int> > pqA;
  std::priority_queue<int,std::vector<int>,std::greater<int> > pqB;

  pqA.push(30);   pqB.push(30);
  pqA.push(100);  pqB.push(100);
  pqA.push(25);   pqB.push(25);
  pqA.push(40);   pqB.push(40);

  std::cout << "Popping out elements..."<<std::endl;
  while (!pqA.empty())
  {
    std::cout << " " << pqA.top() <<" "<<pqB.top()<<std::endl;
    pqA.pop();
    pqB.pop();
  }
  return 0;
}

You can replace less/greater with your own functional if you like, and you can replace vector with any container that has a random access iterator.

StuXYZ 731 Practically a Master Poster

There are basic two instances that require a separate funtion.
(a) when you want different sorting characteristics (b) when you want to store state for the sort.

Let us consider some examples:

A set of points in 3D. (i) Sorting all the points that are closest to another fixed point. (ii) Sorting all the points are closest to a line.
Both of these sorts have "state" to be preserved (ie the datum point/line). Finally, you will find both of these sorts (and others) in almost any molecular simulation [although the 3D point will be replaced with 3D atom].

StuXYZ 731 Practically a Master Poster

I am a bit lost: You cannot create a class from template parameters that are not known at compile time. For example

template<int N>
class A
{ };

You can't have A<i> and since you will only have created explicit instances. e.g. A<0> , A<1>. You can do dispatch of a known sequence. e.g 1-10 but that is your lot with templates.

As for adding parameters that are deduced at runtime, that is ok
do that dispatch first , then do the class dispatch (via hold).
In that case put the parameters into hold. OR do class then the dispatch on runtime, boost::any is a quick way to impliment that.

StuXYZ 731 Practically a Master Poster

You are aware that tan(90) [in degree] is infinity, and obviously, so is tan(pi/2) [in radians] as pi/2 radians == 90degrees.

That is easy to see if you consider that tan is the ration of the length of the two shorter sides on a right angled triangle. Ie by the time the angle nearly 90 degrees the other angle in the triangle is very small. Try drawing that and you will see that you are rapidly getting to LOTS/(Near Zero).

StuXYZ 731 Practically a Master Poster

Just in passing:

First return array[counter],counter; is an awful way to say return counter .
The code does not return array[counter] in anyway.

Second

If I were to enter 100 as the number of numbers. then your code would break since the array is only 70 big.

Third

I think that you would prefer to enter a huge number of random and then obtain the number of 1s, 2s etc. You do not care about the order (yet) . So try collecting the statisics first. For example if your random number part only generated numbers between 1 and 10.
if you did this

int array[11];       // arrays are 0->10

// set array elements to zero here. 

while(counter<amount)
{
  N = rand() % 10 + 1;
  array[N]++;
  counter++;
}

// now print the array.

you have a nice set of distributions because array[1] is increased each time N becomes 1.

StuXYZ 731 Practically a Master Poster

Well first off, I accept that you didn't get any replies at the previous forum, so I will accept that you should re-post. (I might have waited another day or so but that is minor). Given that, I would like to comment on your problem, and actually ask a few quesitons really.

First off: C++ forbids template virtual functions of any sort. You can normally code round that in a slightly ugly way. Several methods around depending on the probelms (many based on encapsulating the function in a template class)

Second: I think that you are trying to do some kind of template dispatch ???? If this is the case then you should look at the boost mpl.

An effective method of doing what I thnk you want is this:

#include <iostream>

class A { public: static void call() { std::cout<<"This is A"<<std::endl;} };
class B { public: static void call() { std::cout<<"This is B"<<std::endl;} };

class Base { public: virtual void go() {std::cout<<"Base"<<std::endl; } };

template<typename T>
class hold : public Base
{
public:
  
  hold() : Base() {}
  void go() { T::call(); }
};


class C 
{
  Base* object;

public:

  C() : object(new hold<A>()) {}

  template<typename T>
  void setHold() { delete object; object=new hold<T>; }
  void go() { object->go(); }
};

int main()
{
  C cobj;
  cobj.go();
  cobj.setHold<B>();
  cobj.go();
  return 0;
}

The above code basically, sets an internal state variable object, that is an effective virtual object. That results in one extra level of …

StuXYZ 731 Practically a Master Poster

I am not sure the problem is actually faulty, but you have figured out templates so the problem is far too simplistic. The problem seems to be based on the type of return and the problem that you have to specify the return type. i.e. your code does not compile since you have to write totalNum = total<int>(aNumber); However, considering your last question.
You can readily make a template that takes an array (size set at compile time, and adds the array up.
e.g.

template<Stuff for you to figure out>
int total( More stuff for you to write )  // defines variable X
{
   int total(0);
   for(int i=0;i<size;i++)   // size is a template parameter.
       total+=X[i];
   return total;
}

int main()
{
   int A[]={1,2,3,4};
   int B[]={9,8,7,6,5,4,3,2,1};
   std::cout<<"Total == "<<total(A)<<std::endl;  // : 10
   std::cout<<"Total == "<<total(B)<<std::endl;  // : 45 
}

}

I think that is the question you are asking. The answer is that you can do that. Have a think about it and let us know how you get on.

StuXYZ 731 Practically a Master Poster

Sorry, kbshibukumar, I am going to be a little picky :) , you do not have to implement the operator< in teh key struct. Consider the code below:

#include <iostream>
#include <map>

struct valueInfo
{ 
  int value1; 
  int value2; 
  int value3; 

  valueInfo(const int A,const int B,const int C) : 
    value1(A),value2(B),value3(C) {}
};

class valueComp 
{
public:

  bool operator()(const valueInfo& A,
		  const valueInfo& B)
    const
    { return A.value2<B.value2; }
};

typedef std::map<valueInfo,double,valueComp> MapCTYPE;

int
main()
{
  MapCTYPE TMap;

  valueInfo B(1,2,3);
  valueInfo C(3,3,4);

  TMap.insert(MapCTYPE::value_type(B,4.5));
  TMap.insert(MapCTYPE::value_type(C,8.4));

  MapCTYPE::iterator vc=TMap.find(MapCTYPE::key_type(1,2,8));
  if (vc!=TMap.end())
    {
      std::cout<<"Success:"<<vc->second<<std::endl;
    }
}

What I have done there is add an external less comparitor. This prevents having to pollute the class with an inappropiate operator< and allows several different comparitors in different maps/vectors.

StuXYZ 731 Practically a Master Poster

errh... sorry Ancient Dragon, but the last line of the file is just "="?
Which was what I was trying to allude to.

The probelm seems to me to be that you read that with a statement while(partin >> charInput >> numInput) Now you get charInput set to "=", which is correct BUT then the program has to get an input into numInput. If the stream is empty then you just wait. So the program just sits. The while loop condition does not get tested because stream::operator<<(int&)
simply never returns.

The better way to do it is to read whole line of input and then divide the line up.

StuXYZ 731 Practically a Master Poster

You have a problem at the last line of your input file.

You read while(partin >> charInput >> numInput) and you have just = on the last line so it reads into charInput and then waits and waits.....

You need to read the char and then the number, and check the status of the file in between.

StuXYZ 731 Practically a Master Poster

Ok this looks like it nearly works so well done!!

But... it is horrible code.

It is very very difficult to read and hence maintain. Especially, if you got asked to develop it on a bit more.

First consider

(a) what happens if I accidentally enter the same input/output filename ?

(b) in brackcheck how do leftCount/rightCount/count differ?. They can easily be combined as one variable.

(c) Consider this:

int main()
{
   // stuff
   {
      // more stuff
   }
}

I am sure that you don not expect that indented the way your program does. The first } is set as E1 that is wrong?

(d) The double while loop in several functions is completely unnecessary.

(e) The switch statement/if , is a mess, use either a switch or an if / else if / else construction.

(f) what is with the mixing '\n' and endl?? Use one (preferably endl)

(g) Note that you always output character, so do that at the end of the while loop with everything else.

(h) Consider this code:

int main()
{
   /*{*/
//stuff
}

Why do I get /*{{*/ in the output....
The solution to that will solve a lot of other problems....

StuXYZ 731 Practically a Master Poster

Ok you have (a) made a few basic errors (b) confused how map searches work and (c) made it very very difficult to read by using C like layout and constructs.

I will address (c) first by writing some c++ like code (others may object but I think it is better than your attempt :)

#include <iostream>
#include <map>

struct keyInfo
{
  int Key1; 
  int Key2; 

  keyInfo(const int A,const int B) : 
    Key1(A),Key2(B) {}

  bool operator<(const keyInfo& A) const
    { return Key1<A.Key1; }
};

struct valueInfo
{ 
  int value1; 
  int value2; 
  int value3; 

  valueInfo(const int A,const int B,const int C) : 
    value1(A),value2(B),value3(C) {}
};

typedef std::map<keyInfo, valueInfo> MapTYPE;
typedef std::map<keyInfo*, valueInfo*> MapPTYPE;


int
main()
{
  MapTYPE TMap;
  MapPTYPE PMap;

  keyInfo A(1,2);  
  valueInfo B(1,2,3);

  TMap.insert(MapTYPE::value_type(A,B));
  PMap.insert(MapPTYPE::value_type(&A,&B));
  MapPTYPE::iterator mIter=PMap.find(&A);
  if (mc!=PMap.end())
      std::cout<<"Success"<<std::endl;

  MapTYPE::iterator vIter=TMap.find(MapTYPE::key_type(1,2));
   if (vc!=TMap.end())
     {
       std::cout<<"Second Success"<<std::endl;
       std::cout<<vIter->second.value3<<std::endl;
     }

As you will see I have dropped your naming convension, sorry, but I hate hungarian notation.

So what have I done. First off I have added a simple constructor for both classes. You don't need them but they keep me happy!

Second I have created both types of map , one that stores pointers to the key value and one that stores the key value. There are not that many cases when you would want to store key pointer but they exist.

Next AND VERY important. map requires that there is a less comparitor. The default is std::less, which falls back to operator< if you define …

StuXYZ 731 Practically a Master Poster

The horrible hack can be cut by a lot, printf("%s%",iter->c_str()); Still it is a bit ugly, but boost::format and alike solve the obvious problems with iostream, and I agree, don't use printf unless you absolutely have to [mainly because it has runtime type problems]

StuXYZ 731 Practically a Master Poster

well we still can't figure it out since I am certain that most of the members of this forum are not psychic.
You have not posted code that actually compiles, so I cannot guess what your real code does.

HOWEVER: I think it is that you don't match the first line/number and then you have only read in the first number not the whole line.
So you need a

while(displayData.good())
   {
      displayData>>tempData;
      if (tempData == number)
         {
          //stuff
         }
      else
         displayData.ignore(1024,'\n'); 
}
StuXYZ 731 Practically a Master Poster

Well there is little to go on here, but....

Consider this, your cat moves from say 100 to 0., then.....
you have written cat.x -= cat.movex; which works fine until
cat.x==0.
Then you write cat2.x += cat2.movex; Fine now consider the sequence if say movex=5;

100,95...5,0,5,0,5,0.. That is because you do not change the sign of movex

you need a

if(cat.x == 0 ) {
  cat2.x += cat2.movex;
  cat2.movex*=-1;
  cat2.y+=cat2.movey; 
}

hope that helps.. if not you are going to have to post a lot more code and that is going to be difficult to get people to debug for you.

Also note: there is another deadly bug.. you have written if (cat.x==0) , what if you say start from 100 and movex == 3. Oh cat.x is NEVER 0. so you should write cat.x<=0 .

StuXYZ 731 Practically a Master Poster

well you seem to under count a little bit.

I personnally like to consider all comparisons. For example: while(j>0 && temp<list[j-1]) That is definately 2 comparisons.
And for(int i=1;i<N;i++) is definately one each time.

Effectively you have under counted a lot of times. BUT note that if you fill this in correctly then you will have a worst case senario since there a several cases were an optimizer will reduce the comparisons.

You also have to be careful about correctly adding extra counts. For example the for loop has N comparisons but is run N-1 times. The while loop has an extra 1 / 2 comparison.

StuXYZ 731 Practically a Master Poster

Sorry the two different names, addTip and addBill was my mistake.
They should be the same. I just wrote it in the message window (not a very good excuse.)

Your problem is that you really haven't written a simple class yet and played with numbers.

consider

Tips(){  double taxRate = 6.5;  }

That does NOT set taxRate. It creates a local variable and then promptly gets rid of it.
So let use consider a simple class. Because without doing this you are never going to get you code correct.

class A
{
     int X;
 public:
     A() : X(11) {}       // set X to 11
     A(const int Y) { X=Y+21; }
     
     void setX(const int Z) { int X=Z; } // THIS DOES NOT SET X
     void setXReally(const int Z) { X=Z; } // THIS DOES SET X  
     void write() const { std::cout<<"X == "<<X<<std::endl; }

};

int main()
{
   A a1;
   a1.write();
   A a2(43);
   a2.write()
   a2.setX(432);
   a2.write();
   a2.setXReally(432);
   a2.write();
}

Now please go and EXPERIMENT with that code until you understand what it does.

p.s. you have to add standard headers. iostream etc.

StuXYZ 731 Practically a Master Poster

No:

The question what is tempData, was because it is declared string but you are comparing it with an integer.

What you have posted DOES NOT COMPILE, hence we can't debug it. What you have to do is POST code that compiles UNLESS you can't get it to compile and THEN post the error message that is causing the problem.

So does userInformation get opened.... I will repeat ADD

if (disPlayData2.good()) 
  { std::cout<<"My file opened"<<std::endl;}
else
   { std::cout<<"File not found/opened."<<std::endl;}
StuXYZ 731 Practically a Master Poster

Help!!!!!! -- This is awful / Where to start!!

Ok consider this:
999*999 is 998001
So count down from that number. Then if you find a palindrom then find the lowest factor. (simple loop works). - -
Divide the number by that factor and repeat.
You will need to keep a multiple of the factors found (Imult)
When Imult gets to between 100 and 1000 check that the cofactor is also between 100 and 1000.
If that is the case then you have finished.

I will also say consider this:

bool isPal(int N)
{
  const int NP=std::log10(N);
  int Nx(static_cast<int>(std::pow(10.0,NP)));
  while (Nx && ((N % 10) == (N/Nx)))
    {
      N -= (N/Nx)*Nx;
      N /= 10;
      Nx /= 100;
    }
  return (N>=1) ? 0 : 1;
}

Does that not find the palindroms with significantly less effort,

The algorithm also is scalable to the long int limit. (can't be bothered to test it further.) What has changed is that the palindromes are much much more limited than the set of multiple produces.

Always be very very aware that marks are handed out for (a) clean code and (b) scalability.

StuXYZ 731 Practically a Master Poster

Ok the usual rant: I hate system("PAUSE") and CLS. They are non-portable, and I can clear my own screen if that is what I want!

Beyond that you haven't given us much to go on.
You don't test if displayData2 is successful? Does "userInformation.database.txt" exist / get opened, have Windows throw a fit about two dots in the name ?
Use if (disPlayData2.good()) to find out.

Then the lines

while (displayData2 >> tempData)
      {
	<< number <<"\n";

do not compile. Did you mean to pass the number to std::cout, and what is tempData??

You need something like

class userInfoRecord
{
   //stuff
};

std::istream&
operator>>(std::istream&,userInfoRecord&);

and then
tempData should be a userInfoRecord and your test should be if (tempData.getNumber()==number)

StuXYZ 731 Practically a Master Poster

Let me just check, I am seeing goto in a program that you want to submit for marking. The only time I have ever seen that was a stunningly bright student in an advanced class showing how scheme could be used to optimize a mathematical C++ program -- and he wrote about 500 words to justify it.

Anyway the error is highighted by Comatose but in the most obtuse way possible. It is actually that you use a global variable int i, rather than for(int i=0;i<number;i++) and then proceed to have TWO loops one in the other that both use i.
Starting from your code line 122, and continuing

for(i=0;i<number;i++)
{
// Your stuff....
 grade[count].aveex=grade[count].exam/totex*50+50;
      for(i=0;i<=number;i++)
      {
	 grade[count].aveq[i]=grade[count].quiz[i]/totq[i]*50+50;
	 grade[count].totaveq+=grade[count].aveq[i];
      }
//more of your stuff
}

Note that i as ALWAYS number at line 10, and your outer loop can only run once.

I think that you have the closure of the loop in the wrong place, but the code is so platform dependent (clrsrn / delay and such) that I simply can't be bothered to run it.

You can also avoid the problem by writing for(int i=0;i<=number;i++) on line 143 BUT again you really don't want i to get to number since you will have an array error.

In short the code is a mess and you have made a mistake by using a variable in too large a scope (i is in ALL of addrecord) when it should only be in the loops …

StuXYZ 731 Practically a Master Poster

Returning to the problem asked:

The problem is that you have created a class that does nothing.
If you take the trouble to create a class don't ignore the values.
You can put tar=100000; and it will make ABSOLUTE NO difference to the code. I think you have confused yourself by using tar in the class AND tar in the function calculate tip. These are DIFFERENT varaibles

What you might like to do:

class Tip
 {
    private:

        const double taxRate;
        double totalTips;
        double totalBill;
   public:
       Tip(const double TR) : taxRate((TR>=0.0) ? TR : 6.50) {}

       void addBill(const double,const double);
};

void Tip::addTip(const double bill,const double tipRate)
{
  //Your code here -- check for 
  totatBill+=bill;
  totalTips+= // your code;
}

also you might like to note that (for a taxRate in percentage) tax=bill*taxRate/100.0; Finally, money is calculated to the nearest cent/penny, and some care is needed about double giving you 0.3333 etc.

StuXYZ 731 Practically a Master Poster

Take my code and look at the loop. It is a test code so you can get to understand loops.

Change the 10 to 11 then recompile and run. Then change the 11 to 12 and recompile and run. Now do you see how it works?

StuXYZ 731 Practically a Master Poster

code integration:

Have a long look at swig http://www.swig.org. I think it is excellent, and have used it with python and lua, and have been very pleased how easy it was.

StuXYZ 731 Practically a Master Poster

Not a problem, lets consider the following code:

int sum=0;
for(int i=0;i<=10;i++)
   {
       sum+=i;
   }
std::cout<<"Sum == "<<sum<<std::endl;

Now what you have there is the sum of the fiirst 10 numbers (55), you add up the even numbers upto 10.

int sum=0;
for(int i=0;i<=10;i++)
   {
       if (i % 2 )
         { sum+=i; }
   }
std::cout<<"Sum (even)== "<<sum<<std::endl;

That is very very close to the code that you are trying to write. It has a loop, and a condition that must be met. note that the initialization of sum is outside of the loop, so is the printing of the result.

StuXYZ 731 Practically a Master Poster

If you have a number to add use this sum=sum+a; or sum+=a; Both do the same thing of adding the value a to the value sum.

you will need to expand you if to only add to sum if a is a factor
you can use this construct

if (condition)
{  
    // statement 1
    // statement  2
    //...
}

Note the braces allow multiple statements if the condition is true

Lastly, thanks for reading the forum rules before posting and feel free to post your next version, when/if you get stuck.

StuXYZ 731 Practically a Master Poster

Please be VERY CAREFUL with this code.

Consider

// THIS IS VERY VERY WRONG!!!!
char * getName(){
    char buf[YOUR_ARRAY_SIZE];
    sprintf(buf,name);
    return &buf[0];
}

The code above is a runtime error, the problem is the you have a local variable (buf) and that goes out of scope at the end of the function. BUT you are passing the pointer to that memory, which you expect to use!!! It is possible/likely that sometime later the program will use that space for something else. Then you will have corrupted the string you are looking at, or even worst you might actually change it!!!!

The orginal is correct, if you want a copy (to manipulate) then make a local copy out of the methods. If you want to change a buffer in the class use a class method.

Sorry for the rant but this kind of error, is normally (a) Very difficult to debug, (b) dormant for a long while so it ends up in customers code.

vmanes commented: Very good point. +7
Salem commented: well spotted +27
StuXYZ 731 Practically a Master Poster

Given all the previous posts, why is this not obvious ??

int counter=0;
open file to read
do
{
    read line
    add/subtract from counter based on { } found.
 } while file.ok

if counter==0 good else bad

Seriously that isn't that difficult ???? If you are good at c++ (which you said) then that is less than 5 minutes work.

Specialization to deal with the stuff in my first post, is another 5 minutes.

StuXYZ 731 Practically a Master Poster

You have some errors: ALL of which should have been explained by you compiler, that you can get to linking is just telling you to get a better compiler (gcc is the minimum and free.).
(a) to (c) stop your code compiling/linking.

(a) student inherrits from Person BUT person is a template class so
which person is student inherriting from e.g. Person<int> Person<std::string> ????

(b) Put the line given in my last post at the bottom of Person.cpp

(c) You cant use Person:: in print_info (student) , so get rid of it, just getFirstName() etc.
[well you can use Person<std::string> or whatever you decided on Student to inherrit from,
but that will give you an unnecessary dependence on your template choise.]

(d) Fixed size array of courseInfo looks bad.

(e) return const references for strings in the getGrade() etc.

(f) void CourseInfo::incrementCount(int &x) {x = x + 1;} This HAS to be wrong!! (I did lol at this!)

(g) Grade/year as strings???

(h) Add some checking etc.

Those threefixes (a-c) get it to compile and link.

Adding your functionallity is another story.

StuXYZ 731 Practically a Master Poster

That looks like an error in getting an appropiate type built.
That can occur when you have multiple files. (compile+compiler flag dependent)

Add a template instanciation template class person<std::string>; at the end of person.cpp and if we are lucky it will fix/change the problem.

Note: If that is the problem, then expect a lot of compiler errors in person since you will not have actually compiled any instance of person yet.

StuXYZ 731 Practically a Master Poster

I am not certain this is the best way but it seems to work.
Note that the disk buffer is also an issue.

ofstream Out("File.log");
// stuff
Out.flush();    // Necessary since you need to ensure that the
                      // data ends up in the buffer.
// Some versions of stdlib have called this with the flush.  
Out.rdbud()->pubsync(); 
// What happens now is OS dependent.
StuXYZ 731 Practically a Master Poster

I think that the problem is not the code, but your maths.

Let us start with a number, e.g 89 as use used. What does writing 89 actually mean: that there are 8*10 + 9.

If you write in base 4 , say 31, you are saying that you have 3 groups of 4 + 1 extra. ie. 3*4+1.

The code you are having trouble with is bascially to convert from a normal base 10 system to the required base.

So put simple, for base4 you need to use multiples of 4 e.g.
4, 16, 64 etc. and express the number in multiples of them plus a units number.

e.g. 47 : well you could write (47) units, but what about : (11) lots of four and 3 units. Then you might like (2) lost of sixteen and (3) lots of 4 and 3 units. i.e in base 4: 233.

To get that number in computer code you, first see what the remainder is when you do Number/Base e.g. 47/4 the remainder is 3. (In C++ that is expresses as 47 % 4). Then you see what you get when you divide by 4 but ignore the remainder e.g.
47/4 = 11. (In C++ with integers , that is 47/4). Now you also have a shorthand that is that you could write a=47; a=a/4; but you can also write a/=4; which is the same.

Hope that helps.

C++ is the …

StuXYZ 731 Practically a Master Poster

Additional to death_oclock, you will need to pass comments and string literals. Since, /* {{ */ and "Some brackets {{{{" and '{' are do not need to be in the counter.

Other than that you need to check that you don't go below zero.
i.e.

int main()
{
//stuff
}}{

Should fail, but a simple counter returns zero.

Finally, you have to be careful of trigraphs. Because ??< //stuff ??> is equivilent to { //stuff } and you could get a mismatch there.

StuXYZ 731 Practically a Master Poster

If a non-static variable is required, it is either local to the method or local to the class. Fine, no problem 99% of variables are just that.

But when a static variable is required, then that is completely different. This way ALL calls to the method regardless of instance have the same static variable. That is typical for specialization of event type in a monte-carlo, base-class has getCell and specialization class knows about the event that can take place, the new energy/velocity of the particle.

StuXYZ 731 Practically a Master Poster

You can get 99% of what you want (if I understand correctly)

You declare a global variable, say outputFlag (or put it in a namespace when doing it properly) and have the function check that. Ugly but gets the job done.

Also have a wrapper function (which takes the flag) and then calls the required function after setting the outputFlag variable.

If you can't touch the function itself (i.e. it is in a library), then buffering the output, and discarding/printing is an ugly solution, but it is ugly and can have side effects on errors etc.

The other slightly more sophisticated way is to stream all your output through a logger, then the logger can be set to take care of the output/no-output calls. But for one function I wouldn't bother, but for several it is starting to look like a better idea.

There are some platform specific methods of getting the backtrace call, but normally that also involves leaving a level of debug trace and limiting the optimization, and they are REALLY messy.

StuXYZ 731 Practically a Master Poster

I don't agree. I think that they have a place in modern code.
I have a few situtation that I think merit them. (as will all good things, go easy on them, even in my biggest code bases, there may only be 10 of them).

Let us consider a function in a geometric matrix class, that say gets a point P and finds the appropiate cell which P exists in, and returns that integer.

That function requires a bit of optimization (particularly for non-orthoganal/non-space-filling cells) and it is found that about 50% of the time the cell is the same as the last search. (P didn't move much). So add a static variable to the method, and record the cell found.

Why not add it as a class static variable? Well that adds a level of scope pollution. Why have a variable in the class, and have to have initializers etc, have someone inadvertently change it. It is a similar argument to declaring variables local to the method, in the class.
you simple would not do it, so I don't see how it is different for a static variable.

I fully agree that if the optimization starts getting a bit more sophisticated, the static variable might need to go to the class level, or be registered to an instance of the class etc, or become a complex monster :)

I also like them when some resource is required on something since the static …

StuXYZ 731 Practically a Master Poster

I would like to politely disagree. I think that the isdigit is a distraction.
First problem is simple:
if you write THIS: cin>>digits then you enter 23d you will get a success with 23 in digits and a very difficult time finding out that you entered 23d.

You first want to read the keyboard input into a string. e.g.

std::string str;
getline(std::cin,str);

Then you need to test what you have read to see if it is ok.

// returns 0 on success -1 on failure
int 
getNumber(const std::string& A,int& N)
{
std::istringstream testStrm;
testStrm.str(A);
testStrm>>N;
if (testStrm.fail())  return -1;

// make sure whe check the remaining spaces:
char xc=testStrm.get();
while(isspace(xc) && !testStrm.fail())
    xc=testStrm.get()

// was the stream completely consumed or did we reach a space.
return (!testStrm.fail()) ?  -1 : 0;
}

This code is designed (I hope) to fail on input like 23d5 , 23 45 ,but not fail on -394
but to fail on --2323.

This code readily can be put in template form, which works for all types with an operator>> defined.

StuXYZ 731 Practically a Master Poster

Your problem is that testClass has a single function that creates a new instance of DbConfig, it has NOTHING to do with the version in int main() , which is dbcfg . Then you try to write out an UNINITIALIZED string.

You would have found that out if you have used initializers for all your private variables in the default constructor.

In short: testClass, should store a reference/pointer to a DbConfig, so that it can work on it.

StuXYZ 731 Practically a Master Poster

well this is the c++ forum, and the reality is that you are going to want a perl/python/ruby/other scripting language. C++ can do it but you are going to write a lot of code to do that. C++ wins out when you have numerics, system level, memory issues, and often code size -- it seems easier to organize than a perl script!

If it is perl, you might want something like:

#!/usr/bin/perl
my @files= split `ls *.jng`;
my $last=0;
for(my $i=0;$i<#$files;$i++)
   {
       if ($files[i]=~/(\d+)/)
          {
             rename($files[i],"newdirectory/".$files[i]) if ($1!=$last+1);
            $last=$1;
          }
   }

NOTE: I do the occasional perl script, I am sure the real perl masters, produce code that is a million times better/robust etc.


Moderators: I believe that this question would be better under perl or scripting languages.

StuXYZ 731 Practically a Master Poster

As MosaicFuneral points out, the compiler can do thousands of things. BUT the best way to find out is to examing the machine code.

Then we learn the following:

The key error in the test code is that you use da/db regardless of the change to the line if (ba==bc) . If you carefully remove that, and stop the strong optimizer settings making cc = 4e7 and skipping the loop. [Well done portland!] then you end up with the the boolean taking slightly shorter than the double on my linux amd 64bit machine under gcc-4.3 and portland. Intel handle integers differently to amd and that is going to change the results as well. Also if you didn't compile your compiler for you exact cpu then you are also going to get rubbish results.

You mileage will differ depending on machine/compiler/OS/Load on the machine. It is normal to do tests a couple of times and THEN do the actual test.

also I dont think you intended to write da == cc in the first if statement (my compiler said statement without effect . It guess you didn't compile with warnings.

The key thing with testing for cpu time, is do it with your real-world problems, then if you make an improvement, you have made a real improvement!

StuXYZ 731 Practically a Master Poster

Please do us all a favour and don't double post on multiple forums
E.g.

http://www.codeguru.com/forum/showthread.php?threadid=469551

You were shown short shrift there, because you code is absolutely awful, and you didn't follow their forum rules either.

In addition you didn't take the time to read ANY of this forums rules.

Putting Richard Chaaya's name on the post wasn't to clever either.

Salem commented: *agrees* +27
Comatose commented: *also agrees* +9
Ancient Dragon commented: Awesume answer +36
StuXYZ 731 Practically a Master Poster

Ok I am going to write some very short code that shows you your main error. [There may be others but this MUST be fixed]

Let us start with const char* . It is good that you are thinking about const BUT you can't randomly assign

class A
{
  const char* X;
public:
  void setC(const char* V)
    { X=V; }
  const char* getC() const {return X;}
};

int
main()
{
  std::string X="fred";
  A obj;
  obj.setC(X.c_str());
  std::cout<<"G == "<<obj.getC()<<std::endl;
  X="John";
  std::cout<<"G == "<<obj.getC()<<std::endl;
}

Note that this print Fred the John.
That is because you are using the pointer to point to the address of your string, then it changes and then you are in a mess. Particularly, when it is deleted because it goes out of scope.

So in short, why don't you use std::string in DbConfig ?
e.g.

class DbConfig {

  std::string datasource;
  std::string hostname;
  std::string username;
  std::string password;
public:
   void setDataSource(const std::string& A)
        { datasource=A; }
// the rest here...
};

If you want to use char* then you should use a copy command, e.g.
strncpy/strcpy or your own loop.

StuXYZ 731 Practically a Master Poster

The real issues are all in #include "DbConfig.h", however, without any includes in TestClass, it will not compile.

Can you post DbConfig.h and we can have a look and maybe solve your problem. (also TestClass.h if it exists)

StuXYZ 731 Practically a Master Poster

This a mess, and the main reason is that you have tried to do WAY to much in one go.

So, you really really need to start again. I can assure you that it will help. Open a clean editor window and start again. The problems of your code are many and most are that you didn't have a short piece of code to test and get right before moving on.

So what to do this time that will prevent the mess of the first one:

Start with one component. Let us say you are going to read some data from the census. What about creating a class for that information. e.g.

class censusRecord
{
   private:

     std::string Name;
     int frequency;
        
   public:
     censusRecord();
     censusRecord(const censusRecord&);
     censusRecord& operator=(const censusRecord&);
     ~censuRecord();

     int getFreq() const;
     const std::string& getName() const;

      void write(std::ostream&) const;
      int read(std::istream&); // returns -1 on failure / 0 success
};

Quick comment on the class (a) it can readily be extended as extra information is required. You can easily add comparison operators if you want to go down the route of stl sort and such like. It lets you get the data so that comparison functors or simple functions to do comparison are easy to write. (b) I have provided read/ write so that you can write operator<< if you wish or just a getline and check the line against the read , if good store the result.

Then you have a class for reading and …

StuXYZ 731 Practically a Master Poster

By the looks of things (I am guessing a bit -- but there is very little code to go on) , you have a rectangle of with top/bottom cordinates.

Then you add 1 to top and bottom but if you reach the bottom of the screen the bottom only is reset. I guess that you draw with a routine that probabily use the top + size so it doesn't work.

Maybe this will work:

if (KEY_DOWN(VK_DOWN))
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
   if (rect2.bottom<SCREEN_HEIGHT-1)
      { 
         rect2.top = rect2.top + 1;
         rect2.bottom = rect2.bottom + 1;
      }
}
StuXYZ 731 Practically a Master Poster

Assuming that the FIRST warning/error from g++ is

./../frontends/include/../../frontends/include/../../libdatastore/include/../../libtimetable/include/../../libtimetable/include/Course.h:26: error: ISO C++ forbids declaration of ‘list’ with no type

Then you error is going to be that from gcc-4.0 and onwards, namespace std is not included in the files like list etc.

ie. You write this

#include <list>

class A
{
   private:

    list<int> Items;
  // other stuff
};

and it is going to fail.

you have two quick options write using namespace std; or change the code to std::list<inst> .

I strongly advocate the latter but if your pushed for time try the first.

NOTE: If you add using namespace std; be very careful that you don't do this:

#include <list>
#include "MyClass.h"

using namespace std;

// other stuff.

Note that the using namespace std, needs to be about the include files or in the include files.

StuXYZ 731 Practically a Master Poster

I wish to comment again, since I now have understood what you are doing!!!! -- Well at least the problem, the code that is a different problem.

Let me see you want to get a position were the columns/ rows AND diagonals all sum up to numbers as a factor 3.

Now let us do this on a piece of paper. Then you will see that you really don't need much computer code.

First question should be given 9 random numbers CAN it be done.
Let us consider the problem: There are three rows, three columns and two diagonals. To get all of them to add up correctly, you need
to change the problem to a matrix of remainders. It doesn't matter if the number is 983231 or 2 both have the same remainder on division by 3.

Convert the numbers to 0,1,2 (or I prefer -1,0,1 but it is unimportant).
Now you add everything up, if the sum is not 0,9 or18 then you can't do the problem.

Next you have to find a solution:
You are aided by the fact that the contributions are
4 points (2 times) [outside middles]
4 points (3 times) [corners]
1 point (4 times) [centre]

The solution has to be symmetric, and the solutions (with the multiplication for occurance must again be a factor of 3).

There are a small set of symmetric graphs and it is quick to …

VernonDozier commented: Simplifies the problem well! +11
StuXYZ 731 Practically a Master Poster

Error on conversion:

Sorry classic error:

int a=9;
int b=5;
 // this gives 1
std::cout<<"Int division "<<a/b<<std::end;

The code you have written gives the error because of 9/5 == 1.
If you write 9.0/5.0 or even 9*(temp-32)/5 you would have the correct answer.

[p.s. Sorry Salem was quicker to posting than me (and he correctly predicted the answer as well!)]

StuXYZ 731 Practically a Master Poster

Let us see what we can do if we think about the algorithm.

Let us start with a brute force algorithm. There are 9! ways to rearrange that 3x3 matrix (362880). BUT there are an infinite number of paths to go between any two matrix configurations.

So the SIMPLISTIC brute force method says that you create all possible patterns, and calculate their connecting graphs (those that can be obtained with one move.) and then find a route from your current position to the new position(s)!

[Sorry, I understood that you have one starting position (unknow at compile time) and a end condition that allows many end positions. I may well have mis-understood you.]

I don't think I like that algorithm !!! It is horrific. The only thing going for it is that you have so many possibilities to make a move that the average exchange.

Ok, can we come up with another SIMPLE method. There are some other possible ways. You can use a routine that I recall as the A* (a-star) route finding algorithm.

I haven't looked it up, it was in a 6502 assembler book I read when I was a teenager. [oh I am that old :( ]. Anyway the method is as follows:

(a) score the current position relative to the win metric.
(b) Make all possible moves and score them.
(c) If a move increases the score keep the best (repeat from (a))
(d) if not back track …
StuXYZ 731 Practically a Master Poster

The option to delete a individual line from the file isn't easy with iostreams.

To simultantiously read/write then you want two fstream objects.
And be VERY VERY careful about flushing the output, and buffered state of the file.

If you need something a lot more high level , boost::filesystem would be were I look first http://www.boost.org/doc/libs/1_37_0/libs/filesystem/doc/index.htm