mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

These errors say that the compiler cannot find the definition (implementation) of the class CPlayer. You must have forgotten to add the Player.cpp file to the compilation process (or its .o file, or the static library to which it was compiled).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Total of food: $2.87
Tax: $0.19
Total for order: $3.06

Man that's a cheap meal! What country do you live in where you can get a soda, burger and fries for 3 bucks at only 6% sales tax!
Anyhow.. I think your code is fine and its almost finished.. what's the trouble?

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok.. well to spare you suspense, and since the code is so near to complete, I guess I can post the solution, for the sin only :)

float sin(float x) 
{ 
        float result = x;
        float term = x;    // ADD THIS
 
        int limit = 15; 
        int sign = -1; 
 
        for(int i=3 ; i<limit ; i+=2,sign=-sign) {
                term = -term*x*x/(i*(i-1)); //
                result += term;                 //make this change
        };
 
        return result; 
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

well from what I understand for your two questions, it seems that you are already essentially computing approximations of sin and cos using Taylor series (first formula) with the recursive computation of the terms (second formula). You don't have a problem... one additional line of code in each function will solve the problem with the answer not being right at the end.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I know how to fix your code, but to let you do it on your own, I will say this: the recursive formula (the second one) is used to compute each _term_ of the first equation one after the other. In your implementation, you use "result" in the recursive formula, not the "term", you need to use the recursive formula to compute the terms and separately add them to get the result.

empror9 commented: thanks +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well this is one problem with:

priority_queue<Job,vector<Job*>,less<vector<Job*>::value_type> > event_list;

In this case, vector<Job*>::value_type is essentially equal to Job* (not exactly, but no need to worry about the difference). Then, now less<Job*>, really means that the elements will be sorted by the comparison "a < b" where a and b are of type Job*, so you will get a sorting by pointer address. I'm sure this is not what you want. So start reading from here, to know how to make something other than less<> for your purpose. So it should be (notice also the * in the first template argument:

priority_queue<Job*,vector<Job*>, some_user_defined_comparison_class > event_list;

>>I just started doing C++ coming from a java background
Welcome to the right side of the fence!

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well this is one way that is with your function, which is totally fine btw, there aren't that many ways to write a sub-string after all:

//notice the return type here.
char* substr(char x[], int n, int n2){
    char *p = new char[n2+1]; //This allocates the memory to hold the sub-string.

    //the rest is essentially the same
    for(int i=0; i<=n2; i++)
        *(p+i) = *(x+i+n); //here x instead of p on the rhs.
   
    *(p+n2) = '\0';
    // I can use this
    cout << p << endl; //p instead of x.
    return p;
}

int main(){
	char x[] = "It should work.";
	char* p = substr(x,3,6);
        ... do something with p ...
        delete[] p; //delete it again
	return 0;
}

But this is a simple way, without using <string>:

int main(){
	char x[] = "It should work.";
	char* p = new char[7];
        memmove(p,&x[3],6); p[6] = '\0';
        ... do something with p ...
        delete[] p; //delete it again
	return 0;
}

Or even better:

#define MY_SUBSTR(RETURN_POINTER,STRING_POINTER,START_INDEX,SUBSTR_SIZE) = new char[SUBSTR_SIZE + 1];\
memmove(RETURN_POINTER,&STRING_POINTER[START_INDEX],SUBSTR_SIZE); RETURN_POINTER[SUBSTR_SIZE] = '\0';
int main(){
	char x[] = "It should work.";
	char* p = MY_SUBSTR(p,x,3,6);
        ... do something with p ...
        delete[] p; //delete it again
	return 0;
}

Don't worry if you can't understand the last two.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Please post with code tags!

This line in displayTotal:

for (int x = 0; x < 12; x =+ 1)

Should be this:

for (int x = 0; x < 12; x += 1)

Notice the += instead of =+ (this would mean "x = +1").

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

As it is now, the original string gets replaced by the sub-string, so you do get the sub-string back from the function. But if you want it like you said. First you need to allocate new memory for the sub-string, with the right size (n2 + 1). Then you write into that memory exactly the way you are doing now, and you give the pointer back as output. But,
1. you need to allocate memory for the sub-string with "malloc()" (if you are against <string>, I presume you are programming in C, otherwise use "new")
2. the string that is outputted needs to get deleted, and it needs to correspond to how it got allocated, so if you use "malloc" then delete with "free()" (if you use "new" then delete with "delete").

The above second point is the reason why, generally, people don't program functions that return pointers to newly allocated memory, it's not safe to assume the caller will know which deleter to use (in case of hybrid C/C++ code). So usually, you add a parameter to the function which points to a place with enough memory to store the sub-string.

Finally, save yourself the trouble and just use "memmove()"!

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Kubuntu 9.10 (waiting for 10.10.. with KDE > 4.4), I personally just have it installed on an external drive (but not flash), this way I avoid messing with the windows boot-loader.. just plug my harddrive before starting and I get into linux, leave it unplugged and I get to windows (which I keep for games and the engineering software I have to use for my work).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>treasure on each space line could be 3,2 or 1 but not 0.
I don't understand that, but for the rest..

You can call rand() as many time as you want, so that solves the problem of having multiple treasures.

Also, to avoid walls and borders and other treasures, just make a loop that generates a new treasure position, checks if the spot is already occupied by a wall or border or treasure. If not, then set that position to a treasure. If yes, it is already occupied, then go back to the start of the loop, generate a new position for the treasure and repeat. Repeat this loop until you have placed all the treasure you wanted to place.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well I'm a linux user... so my IDE of choice is KDevelop (compiler is of course gcc, as provided by linux), for debugging: gdb (for line-stepping) and valgrind (for memory issues), although I rarely use them.. one of the perks of having a lot of experience.

For windows, I used to do all my programming with Borland C++Builder, but now it is a bit outdated. I heard many people like Code::Blocks for windows, and its free, so is the newest versions of Visual C++ Express (but you need to install the compiler separately and do some configuration work, I think..).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

This means that the compiler cannot find the definition of the function calcCelsius that matches the prototype:

void calcCelsius(double); // the "_cdecl" thing is just the default calling convention.

So either you didn't provide a definition for that function, or your definition doesn't match the prototype exactly, or you didn't put the cpp, where that function is defined, on the compiler instruction (i.e. you didn't include it in the compilation of your app).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

That's nasty.. I hate VC++! I think you must be missing some headers, or at least VC++ doesn't find them.. these things are hard to find by yourself, especially since VC++ is probably the compiler with the least useful error messages (no back-tracing!).

What I do in these cases, I just copy one entire error message and google it, then the next and the next... I can bet you that others have had the exact same problem, and eventually you find a forum thread or other web source with the solution. (if you find it, post it back here as well, just to increase chances for the next poor fella who runs into these errors)

Relax, all the errors are essentially the same, so probably only one solution will fix'em all. And it probably has nothing to do with your code but with the installation and the paths to the includes.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

1. overloading with different number of arguments is fine, it works very well.
2. function templates will also do it well (although it boils down to overloading at the end, but just less code, if used properly).
3. consider default argument values (which allow you to call one function with different number of arguments, given that some can be defaulted), another form of overloading, for a function where there is one or more parameters that often don't matter (i.e. have a default value) like from your code:

void ReadFile_FillStruct_1(string _fileName, vector<string>& _vectorStorage, bool _boolArg = false); //notice the = false (default value), in the prototype only, not in the definition

4. consider wrapping the arguments in another class or struct or union (look up tuples) as templates or not.


From the looks of your code example, I get the feeling that you are implementing a "serialization" library. If you are comfortable with templates, or if you are willing to get comfortable with them, consider look at this almost-standard library, at least for inspiration. I would not recommend you look at it before being comfortable with template meta-programming, because of risk of head explosions!

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Your prototype and your definition should always match EXACTLY, that is true for functions and everything else.
Since the point of the prototype is to tell the rest of the code exactly how the function, that is defined later, should be called, so it is meaningless if the definition does not meet the prototype in terms of number of arguments, their types and qualifiers, and the return type (and also the calling convention and any other function qualifiers).

two exceptions:
1. The parameter names in the prototype are not necessary or required to match the definition, but the types and number of argument must match exactly, including the return type.
2. If you have a default parameter value in the prototype, it should not appear in the definition.

there are a few other differences with function templates, but that will be a bit further down your learning process.

So for all that matters, PROTOTYPE == DEFINITION

so in the above code, the definition of displayPayment must be:

void displayPayment (double monthPay, double& whateverVariableNameHERE)
{ .. }

to match its prototype.

PS: please put your code between tags, for readability.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Consider something like this:

#include "Cores.h" //I assume this would contain all GeneralCore, GraphicsCore.. but I would suggest you have one file per core, in fact one header per class in general.

namespace my_engine {

class Engine
{
   GeneralCore mMyGeneralCore;
   GraphicsCore mMyGraphicsCore;
   GameCore mMyGameCore;
   LogicCore mMyLogicCore;
};

};

// in GeneralCore.hpp
namespace my_engine {

class GeneralCore {
  ... whatever ...
};

};

// so on for the others cores.

With proper implementation of all the cores and the Engine class, all you would have to do to start the game would be:

#include "Engine.hpp"

using namespace my_engine;

int main() {
  Engine MyGame(.. some parameters like which game logic to start ..);

  MyGame.run(); // or something like that.
};

I have always done something like that for my past game engines.

In response to:
>>Is there a way to create one class out of many different classes?
Well it's a bit vague. Consider this discussion. That gives a few guidelines in general with respect to multiple inheritance (I would not recommend that, but the discussion there also discusses all the alternatives which are probably better suited for your application). You should rely a lot on polymorphism, abstraction and encapsulation. Make sure to understand those topics before making too many structural decisions about your engine.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Many bigger projects use building (compilation) tools such as cmake which select compilers based on the source file extensions, and .c would be passed to the C compiler. Some projects often use .c files (C code) as third-party sources for some special purposes such as hardware drivers and other IOs, i.e. low-level libraries. Or often "scientific" coding involves algorithms that were programmed in C (or even in Fortran) and it's often more robust to mix C and C++ instead of porting the C code to C++, because that could introduce bugs (during the translation, e.g. typos) into these older and well-proven C algorithms.

About .c being supported by c++ compilers, that depends on the compiler, some ignore extensions others do not. But generally speaking, compiling C source files in C++ can sometimes work just fine, sometimes not at all, and sometimes it will just produce a lot of warnings like "use of old C-style cast" or "... will violate strict aliasing rules", etc.

But coding c++ code in a .c file is not a good idea, and really what would be the point of that? to make the file name two characters smaller?

Read this. For a more detailed explanation of mixing C and C++, the why and the how.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

In the constructor, you shouldn't have "int boar..", repeating the type (int) will declare a new variable called "board" that is local to the constructor. so you are initializing a local array board and never initializing the data member "board". So that is why the private data member "board" remains with garbage values.

This is allowed in the c++0x standard (add flag "-std=c++0x" to gcc to compile):

ScoreBoard::ScoreBoard() : board({-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0}) { };

Otherwise you have to initialize them one by one, i.e. with a loop from 0 to 14 to set to -1 and finally setting the last element to 0.

Ancient Dragon commented: well said. +31
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

From looking at the original problem, it may be required, and it makes the "drawing vertically" problem a bit easier, to sort from most often occurring letter to least occurring letter. But as jonsca said you can do it without sorting too.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, in the expression "const QMimeData* const", the first const means that the QMimeData is not changeable (constant) and the second const means that the pointer to it is not going to change either. If you don't need to change the pointer (i.e. create your own QMimeData object), then make your list QList<const QMimeData* const>.

But, possibly, depending on the implementation QList, you might not be allowed to do that because a const QMimeData* const is not well copyable. So in that case, keep QList<const QMimeData*> and make this line instead of what you had:

copiedList->push_front(const_cast<const QMimeData*>(clipboard->mimeData(modes)));

I pretty sure this will work.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

It looks a bit to me, from your class names, that defining your own namespaces might be a good option for you to consider instead of nested classes.. just a suggestion.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, the brute force method for this is to just make the list of all games that are to be played (as you have there) for x number of teams (btw. the number of teams have to be even for this to work, otherwise, every day there is one team with no opponent). Then you try every day (out of x+1 days) to come up with x / 2 games that can be played without one team being repeated amongst the pairs for that day. Then you eliminate all the selected games for that day from the total list of games left to be played and move on to the next day and repeat the process.

Of course, there must be a more clever way to do this, but that will work at least.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well stack overflow! That's too much memory usage. You can set the stack size as a compiler option, but I have never needed to, so I don't know the exact compiler option.

Other than that, you might want to learn to ident the code a bit better, it usually helps you debug things.

You might want to have a second look at line 39, if d > delta, this is an access violation.

Also line 285 is an access violation too ("lo" has been deleted at this point, so don't use it again after line 283, even just trying to print its value will throw an access violation).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

B=N*I*R*R/2[R*R+x+x]^3/2;

Is not a valid C/C++ syntax. the ^ operator is not for power (it's binary XOR which I doubt is what you intended). C/C++ is not matlab or mathematica or a hand calculator.

If the function is, as I understand it: B = (N * I * R * R) / (2 * (R^2 + x^2)^(3/2))
Then in C++ it is:

B = N * I * R * R / (2.0 * pow(R*R + x*x, 3.0 / 2.0));

BTW: the value R is the radius of the coil, not the resistance, and x should be declared as a float. Oh and PI = 3.14159.. not 3.14.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

If I am creating an array in a function then I go out without deleting it then in another function I create an array with the same name and delete it, can this cause problems?

YES, very much so. If you allocate an array in one function (assuming the array pointer is local to the function, that is, declared inside the function) and don't delete it, it is lost memory (memory leak or dangling pointer). You will never retrieve that pointer again and will never be able to delete its memory. Even if you re-enter the same function again, the pointer will have a new value that doesn't point to the memory you allocated the last time around. So, any memory you allocate with "new" inside a function has to be deleted before you leave the function.

Declaring a pointer for the array with the same name in another function has the same problem, that pointer has absolutely no relationship with the one that points to your allocated memory. The scope or life-time of a variable is limited to inside the first "{ }" around the place where it was declared (data member of classes are one exception). Think about it, otherwise, that would mean that any variable you create would have to not have the same name as any other variable in any function in the entire set of C++ standard libraries, any other libraries you use, and all of your own (if that was the case not …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, there are always ways on the internet to get things like that for free.. but it's not very legal... these are the things I call "extended student discounts" to make it morally acceptable.. but still, illegal.. so I can't recommend anything.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

djextreme is right, I'm not interested in seeing the final, working code (and probably none of the "advise-giving" posters are either), so it would only be of interest to those who are dishonest enough to be browsing the internet for a homework freebie.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First, you are incrementing your index j twice in the loop, once at line 9 and once at line 47. That would skip one line. Second, you are starting the "//For each i > j: row i - (Cij/Cjj)* row j" part with "i = j" (because j++ returns the original value of j) not with "i > j" (or i = j + 1) as you should and said in the comment line. So to fix it all:

//replace this:
i = j++;
for(int row_i = i; row_i < N; row_i++)

//with that:
for(int row_i = j+1; row_i < N; row_i++)

Now, your almost there, just a simple back-substitution left to do!

Nice quality code btw, simple and easy to read, not very usual on this forum. If you want to clean up even more (like you did with the start variable), note that "p" is also useless...

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You did add ">> size" for line 66 as well, right?

Check your .dat file to make sure the students were properly saved.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster
//replace this:
         grade = new int[size];
         
         Class >> name >> last >> age >> gender; 

//with that:
         Class >> name >> last >> age >> gender >> size;

         grade = new int[size];
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I was just about to say something about closing this digressing argument. So Garrett, if you are not convinced, either test it or we can agree to disagree, or you can start another thread on that to see what other people think.

But I enjoyed the debate! :)

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Oh sorry when I said CreateStudent, I meant StoreStudent. my bad.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I found this thread to be explaining quite clearly what I tried to explain, nobody seems to disagree with me either. I have looked around the web about this, but to no avail, nobody seems to point out any difference of pass-by-value or pass-by-reference guidelines when it comes to inline functions, methods, or constructors.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Oh, you're right. Well, save it in the file, just before listing the grades. So in CreateStudent, save "size" just before all the "grade" elements. Then in both DisplayStudent and DisplayClass, all you need to do is read "size" from the input file, then allocate the required array in "grade", and read the individual grades.
Or, if size should be the same for all students in a class, then you can save it at the very start of the file.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

This is an old version of your code, this will not compile. Again you have "uninitialized variables", like you had before, that you cleaned up but now you put them back in. In both functions you have:

int size;        //BIG ERROR! size = random-non-sense and is not a constant.
 int grade[size]; //BIG ERROR! grade is allocated to some random size.

If your compiler is compiling this, get a new one, because no compiler should accept this to be compiled.

Revert back to the code of your previous post, with the one line change I made and start from there. These two functions are not the same as before. Be diligent and keep track of your changes. And solve the warnings you get when compiling with -Wall.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, I don't agree with AD about how writing beyond an array will corrupt the heap, it might throw an Access Violation or segmentation fault, but not corrupt the heap (it would be wonderful if it did, it would make heap-related bugs so much easier to find! I know by experience.. painful memories..).

I would suspect that you get to the deleting part before you get to the allocation part, somehow, or that you delete twice (the rest of the code could tell). I have a hunch that you get an "Access Violation writing a location 0x00000008" when you compile in debug mode, if your compiler is set to initialize the uninitialized memory to 0. And when not in this debug mode, the pointer "o" or the pointers it contains is/are pointing no-where and trying to free it/them corrupts the heap.

The heap gets corrupted (well corrupted in a way that you are lucky enough to get an assertion, most often you don't and it just makes your program go completely crazy) when you try to free memory outside of the chunk of RAM that your App's heap is managing.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well maybe you know something you don't want to tell me... but for all I know, and I do acknowledge that I could be wrong but I have never read anything to the contrary, the process of compilation of an inline function is something like this. Say you have a simple setter function inlined (assuming the compiler _chooses_ to inline it, which it probably will):

class A {
  private:
    double value;
  public:
    void setByValue(double aValue) { value = aValue; };
    void setByRef(const double& aValue) { value = aValue; };
};
int main() {
  A object;
  double param = 10.0;
  object.setByValue(param);
  object.setByRef(param);
};

The compiler will not, at first, assume _anything_ about the usage of the passed parameter, because it cannot, a compiler is not a human who can look at this right away and know what's best. So it expands to something like this:

int main() {
  A object;
  double param = 10.0; 
  //inlines the setByValue:
  {
  double aValue = param; //copies to temporary "aValue"
  object.value = aValue;      //sets the data member
  };
  //inlines the setByRef:
  {
  const double& aValue = param; //takes address (or ref) to param
  object.value = aValue;
  };
};

Once this is laid out, it will look at it and do a DU-chain optimization to clean useless temporaries:

int main() {
  A object;
  double param = 10.0; 
  //inlines the setByValue:
  {
  object.value = param; //just sets value directly, no addressing and no copying.
  };
  //inlines the setByRef:
  {
  object.value = param; //just sets …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I changed one line of code:

int Student::StoreStudent(string ClassName, string name, string last, int age, char gender,int grade[]){
    // This function stores the student information into the file
    int size = 5; //added the "= 5" here, and it works (for 5 grades only, of course).

"size" was undefined before and you used it without initializing it, so your program was doing weird things. Now it will work except for the class summary which has a few integer division issues and stuff. But, of course, you need to make changes such that it works better for a number of grades different from 5. But by starting with this working version, incrementally make things work for other than 5 and run often and it should go smoothly.

Also, a tip, compile your program with the flag -Wall, this will help catching those mistakes. As in:
> g++ test.cpp -o test -Wall
test.cpp: In function ‘int DisplayClass()’:
test.cpp:187: warning: unused variable ‘k’
test.cpp: In member function ‘int Student::CreateStudent()’:
test.cpp:281: warning: unused variable ‘Age’
test.cpp:282: warning: unused variable ‘Gender’
test.cpp:283: warning: unused variable ‘Grade’
test.cpp: In member function ‘int Student::StoreStudent(std::string, std::string, std::string, int, char, int*)’:
test.cpp:348: warning: no return statement in function returning non-void
test.cpp: In function ‘int DisplayClass()’:
test.cpp:186: warning: ‘size’ may be used uninitialized in this function
test.cpp: In member function ‘int Student::DisplayStudent()’:
test.cpp:356: warning: ‘size’ may be used uninitialized in this function

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

no, not me.. I don't use MFC.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well... I have copy-pasted your code.. and its working fine on my side. There are a few issues with computing the average grade (you have fixed the number of grades to 5 in there), but otherwise its working. So it has to be some code that you did not post because I filled a few gaps of the not-posted code and it works fine.

Here is the console print:
Choose an option:2
You've chosen option: 2

Enter a class:
firstgrade
How many students would you like to enter:
2
Enter student information:
Enter first name:
bob
Enter last name:
gibbs
Enter age:
8
Enter gender: (M or F)
M
How many grades would you like to enter?
4
Now enter 4 grades:
Enter grade 1:
80
Enter grade 2:
75
Enter grade 3:
65
Enter grade 4:
90
Enter student information:
Enter first name:
mindy
Enter last name:
singer
Enter age:
9
Enter gender: (M or F)
F
How many grades would you like to enter?
4
Now enter 4 grades:
Enter grade 1:
70
Enter grade 2:
68
Enter grade 3:
95
Enter grade 4:
87
Choose an option:3
You've chosen option: 3

Enter a class:
firstgrade

bob gibbs 8 M 80 75 65 90 0 62 A
mindy singer 9 F 70 68 95 87 0 64 A


Choose an option:5
You've chosen option: 5

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

MySQL is another simpler and free database server too. My advice is to browse your GUI library for built-in database functionality (I know Borland VCL has all sorts of nice GUI widgets for database programming, but it's a bit outdated (I haven't done database stuff for a long time), I'm sure MFC or Qt have plenty as well, this will be a big time-saver).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

In MFC or any other GUI library, things are Event Driven which mean that the execution of the program is not your typical main_while_loop type of thing you find in procedural programming. Your application is simply reacting to events (handling) as they come, so your question is a bit bizarre, it seems you are trying to mix event-driven execution with procedural execution. You can have both, but on separate threads of execution (in fact that's what happens by default because starting up Windows Message Pump will start a thread of its own (and actually several threads) to handle the incoming events and messages).

So for things to look at for achieving whatever goal to which this jumping problem is a problem for. I suggest looking into the topics of: state machines for GUIs, multi-threading (that goes without saying), and issuing user-defined windows message.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

In your StoreStudent method, you open the file with:

Class.open(ClassName.c_str(),fstream::app);
//But it should be:
Class.open(ClassName.c_str(),fstream::app | fstream::out);

This is because only setting the opening method as "app" for append, will (weirdly enough) not set it up for either reading ("in") or writing ("out") so your file writing operations will fail. NOTE I may be wrong on this, but that's what I can see as wrong.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>> you're telling that I might change value of parameter during function execution, so a copy of input argument should be made.

Sure, it says that in _theory_, but, sending as "DataType", the copy is created as temporary and optimized away easily by 99.9% of compilers. If sent as "const DataType", no copy is made but it also can no longer be used as a variable inside the function, so the end-result is the same but more restrictive in the coding (but this can be an advantage for const-correctness, that I agree fully with!). If sent as "const DataType&" or "DataType&", a temporary pointer is sent (which is as expensive or more expensive, in this case, than sending a temporary double variable) and the variable is used by reference everywhere in the function, an extra layer of indirection in the temporary that compilers will find more difficult to optimize away. For _inline_ functions, it's even easier for the compiler to optimize so all of the above really boil down to the same executable code, but if not inlined, passing a double by value is better so either
- "const double" if you don't want to use the parameter as a variable inside the function, but I would say 98% or so of the time it's exactly the same as "double";
- "double&" if it has to be changed, i.e., as an input and output variable;
- "double" in general for all normal input parameters.
- …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Sure that works.. doesn't it? Compile, run, and see!

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

One big problem:

// Variables required for the function
...and all the code that follows...

All those variables you declare are not initialized to any value, this can be dangerous and I would suspect (or know) that your compiler is probably complaining a lot when you attempt or succeed to compile. One case of this being wrong for good reason:

int size;
  int grade[size];

First of all this will not compile because "size is not a constant expression" (this will be the compiler error). And second, it's a logic fault in the sense that what this mean is you have a variable called "size" which has no value and then you _try_ to allocate an array "grade" of that size which is undefined, it could be 0 or 734912423 or anything, that's a second reason why a compiler will object to compiling this code.

So to fix that, you need to declare "grade" as a pointer (initialized to NULL) and allocate dynamically (with new) the array of grades, once "size" is known, like you do in the constructors. All the other variables declared there should be initialized even if the initial value is a dummy value, that's not absolutely necessary, that's just good programming practice. Also, consider moving the declarations of the variables closer to where they are used, it's less confusing, more efficient, and less chance of name-mangling.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

As suggested by firstPerson, class or function templates are typically the best way to achieve common functionality for different types. So you can look up templates for info on that.

Also, operator or function overloading can make the code more uniform (as in the above, your functions don't need to have different names). Take the "ostream" class of the C++ std libraries for example, overloading of the operator << for all types makes all writing (or output) operations of any type look exactly the same (i.e. cout << int_var << double_var << custom_object << "literal string or flag ->" << endl).

Combining the above two concepts should solve your problem very nicely.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

i

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Sorry too for mistaking he for she. Tesuji is right about the fabs() That is probably why rows get switched wrongly.

You should also understand that pivoting is part of the Gaussian elimination. The algorithm is that for every column, you find the row with the maximum (fabs()) value at the column, pivot with the "start" row (whose index is equal to the column index), eliminate the lower off-diagonal entries by adding that row * <some factor>, and repeat until the last row. So the pivot step is in the middle of the main elimination loop. So if you try to pivot for the first column then the next and so on without doing the elimination step, it is not going to do anything useful besides randomly swapping rows around.

@Tesuji:
1. I don't see any endless loops, just properly used "do { } while();" loops.
2. solve_b computes the RHS vector for a solution vector "s" (for checking if the algorithm computes "s" back again)
3. solve_x finds the actual solution vector for Ax = b.
4. the elimination part is not done, she is still at verifying that the pivot step is working correctly (which is a good way to program, kudos to vavazoom). BTW this is a Gaussian elimination, not a LU-decomposition (LU-decomp. is one, slightly better way to solve Ax=b, but this problem is on Gaussian elim.).