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

I made up the term, so no worries. Basically it means treating every object as a sequence of bytes that can be written to some storage medium as-is and read back without any issues. This brings four categories to mind, in order of least to most complex in terms of serialization:

  1. Verbatim sequences of bytes. These will pretty much be safe to perform naive serialization on because there's very little that can get in the way of safe and lossless I/O.
  2. Plain Old Data (POD). There's no magic going on behind the scenes, such as virtual tables. POD types are generally safe to "pun" into sequences of bytes, but the issue of byte ordering does come up. For example, if you pun an int as big-endian and try to restore it as little-endian, you're not likely to get the same value. In this case you can correct the issue by reading and writing the bytes manually in the same order.
  3. Non-shallow data. Pretty much any time you have a pointer, writing the value of the pointer is pointless because upon restoring the pointer, the address may not be valid any longer. For this kind of thing you have no choice but to perform a deep copy to the storage medium.
  4. Non-POD. All bets are off, there's voodoo going on under the hood that you don't know about and bitwise serialization will very likely blow up in your face.

5. An object hierarchy where there are cross-references (references or pointers) …

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

What I call "naive serialization" is this:

class A {
  //some stuff.. possibly arrays, pointers or resources of any kind. 
};

int main() {
  A a;
  ofstream outfile("foo.dat");
  outfile.write((char*)&a, sizeof(A));
  return 0;
};

The above is "naive serialization", which is probably a term I made up, so looking it up is not going to yield anything. Possibly also because "naive" is an understatement in this case, but I couldn't give the appropriate name without violating Daniweb's policy on foul language!

I really really recommend you that a good read of the description of the Boost.Serialization library, it will answer your questions.

The way you are describing your solution, really doesn't seem good, very dangerous in fact. Here it is line-by-line:

>>I revisited the I/O section in the standard.
The I/O section of the standard is really not going to help for this purpose, read Boost.Serialization instead.

>>Made every object inside the program static
That's a horrible restriction to impose on your software. This will be a huge burden on all your future development in this project. You ought to find a method that doesn't involve such a restriction (in fact it shouldn't impose any restrictions, my serialization library doesn't and neither does Boost.Serialization).

>>so there can't be an issue regarding the size of the objects being stored.
The size of objects are always constant, regardless of whether they hold dynamic data or not. Dynamic data (i.e. a dynamic array or STL …

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

It seems about right to me. I don't know about your getValidInt and getTotDeduct, but if they work, than this should work. Have you tried compiling and running?

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

In GCC (MinGW under windows), the flag to turn on almost all warnings is the -Wall flag, which means the command-line to compile is:

$ gcc my_source_file.cpp -Wall -o my_program

(in MSVC, the same compilation flag is "/Wall")

However, if you use an IDE, there is usually a "build options" or "project property" menu button. It will usually show a big list of compiler options. You just turn on every one of them that says "enable warnings for ... ", or at least enable the one which says "enable all warnings (-Wall)".

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

Just change element to any type that makes sense (like unsigned char or float). And it should work.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster
void _medianfilter(const..

Names with leading underscores are reserved by the C++ Standard article 17.4.3.1.2 for implementation-specific names in the global scope. It is not recommended to use names with leading underscores in any code that you write or use. If you need to "hide" a function, standard practice is to put it in a "detail" namespace, or append "_impl" to the end of the name.

For the rest, you haven't really asked a question, at least, not a specific one.

BTW: the code you posted is not specific to Borland C++Builder, it is just normal C++ code (well actually it's C-style code... only the new/delete thing is from C++, the rest is just C).

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

I think that at line 6, you meant to write:

while((ptr != NULL) && (item >= ptr->info) && (!found)) {

Notice the >= at in the second comparison. Otherwise, this function will always output false. Hint: You should always turn on all the warnings when compiling. This code would have given a warning as such "line 11 can never be reached" because the condition for entering an iteration is the same as for the if-statement, so the compiler would be smart enough to see that (and compilers don't miss typos like humans are so good at missing).

The rest looks alright. At line 49, "delete ptr;", if your implementation of the Node's destructor also destroys the next Node, that could be a memory problem (if it doesn't then it's OK). You could just set ptr->next to NULL just before the delete if you need to fix that.

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

You have, at line 17, a variable called "WriteResults". This is the same name as one of your functions. What happens is that this local variable "hides" the global function (because identifiers of local scope hide any identifiers of larger scope that happen to have the same name). So, at lines 22 and 24, the compiler thinks that WriteResults refers to that local variable and not the global function, so it says that it "does not evaluate to a function .." because that local variable is not a function. So, since this variable is not used anyways, you should probably just take it out, or find a different name for it.

Also, you must have a perfect match between the function declarations (line 7 to 12) and the function definitions (lines 29, 39, 50, 60, 68 and 73) and that includes the correct function name (C++ is case-sensitive) (but not necessarily the same parameter names), the correct number of parameters, and the correct type for each of them (and correct result type too).

And I think your function calls (line 19 to 24) seem odd, you might want to double-check them (for instance, WriteResults has no return value (void) and yet you store that result in the variable results at line 22).

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

Line 40, the single equal sign should be doubled == for comparison. Compiling with all warning on would have caught that typo (use -Wall as a compiler flag).

Transcendent commented: thanks man +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@NathanOliver: The <algorithm> version of sort cannot be used for the list container because it requires a random-access iterator (and list is a linked-list so it only provides a Forward and Backward Iterator concept). The way the OP did is correct.

@atticusr:
The sorting algorithm relies on the comparison (by default) of two elements using the < (less-than) comparison. So, the underlying type has to have that operator defined. In other words, if you have "list<MyType> l; MyType a, b;", you have to be able to write "a < b". To be able to do that for a custom type, you need to overload the operator <. As so:

struct cProg3
{
  char lname[21];
  float avg;
  int gSize;
  cProg3();
  void Read_m(fstream &Infile);
  void Read_g(fstream &Infile);
  //Overload operator < here:
  bool operator < (const cProg3& other) const {
    return (avg < other.avg); //compare by average.
  };
};

That should work.

NathanOliver commented: thanks for straightening me out with that +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>im trying to use the address,hardcoded at compile time, at that address, to read in the bytes starting at that address till the end of the return..... -thx

??????

If you want the "address hardcoded at compile time" that won't be of any use at run-time. At compile-time, all function addresses are relative to the file, while at run-time they are in a virtual address space of the process (i.e. they are no longer the same).

If you want the address at run-time, then there is no native way to do this easily (I mean you are talking about extracting the value of the "instruction register"? I don't know of anyway to extract that without writing assembly code).

It looks more to me like you want to take a peak at the machine code of a function. For that, you can either set a break-point in your IDE/debugger and inspect the assembly there. Or you can just compile your program into an assembly listing (using option -S on gcc and others).

Please say what you want to accomplish, not the means by which you are trying to do so, because, from the unusual nature of it, it doesn't seem like it's the best method.

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

Line 40 should have a _double_ equal sign "==". Watch out for typos like that. And turn on all the warning when you compile! -Wall or /Wall depending on your compiler.

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

The compiler "mike_2000_17" gives this error:
"Error at line 34: function "GetOddElements" reaches end-of-scope without returning a value"

The reason why your version that uses references is not working is because references are not copy-assignable, which is a requirement of all STL containers.

As for the bigger question. This is not a very robust way to have a sub-vector that is linked to another vector. You should look into the concept of "array views" (used in several libraries such as Boost.Graph, Boost.Multi-Array or -Index, and others too). Basically, you should wrap a reference to the vector object and define some index transformation to change the "view" that this object takes on the underlying container (this is for example a nice way to implement the transpose of a matrix without any copying).

daviddoria commented: Thanks as always Mike! +5
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, I can help to make the description more concrete:

gross income: Would be a number (int, float or double) that the user is asked for and will enter.

itemized deduction: Would be an array of numbers (int, float or double) each representing a tax deduction amount.

The taxpayer's deduction is either the standard deduction (4,150) or the itemized
deduction, whichever is larger: This means you would need to take the sum of all the deductions (sum of the array elements), then take the maximum number between 4150 and the total of the deductions.

Taxable income is determined by subtracting the taxpayer’s deduction: Take the gross income and subtract the value found at the previous step. Then, set the taxable income to the maximum number between 0 and the result of the subtraction.

Total tax is determined by multiplying the taxable income by the tax rate (0.17): Multiply the number you got in the previous step by 0.17 to obtain the taxes to be paid. That number should be the output of your incomeTax function.

Finally, in main(), you first ask the user for the gross income, then for the list of deductions, call the incomeTax function with these two parameters (income and array of deductions), and finally, print out the result of the function (i.e. the tax to be paid).

If you want any further help, you will have to show some progress towards implementing the above in C++ (i.e. some …

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

I agree with Narue, there is no escaping it. You have to implement the serialization method for each class. If you have a hierarchy of classes, then make it a virtual function and in each class you store its data only and call the base class method to serialize its data (you can do it in either direction, e.g. call the base class serialize first and then serialize the derived class' data, or the other way around). Make sure that both serialization and unserialization functions do it in the exact same order. Finally, you might want to take a look at Boost.Serialization for a good example of how to do this, and you might even want to use it because it is not very intrusive.

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

Well, GLUT is a limited library. It is not really meant for complex applications. Why don't you use wxWidget or Qt to create the window then and render your openGL scene inside the wxWidget window, as in this tutorial. And even better for Qt.

Nick Evan commented: Excellent advice as (almost) always ;) +16
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

If you are using GLUT for making the window, why not use it for the mouse and keyboard events too. It has all these things built into it. Look here.

Generally, the mouse events and keyboard events are intimately linked to the window context. So, that is why any library that creates a window (like GLUT, SDL, Qt, VCL, wxWidget, etc.) also has all the mouse and keyboard event facilities as well. They aren't really separable or standalone (for instance, you can't create a window that doesn't have any handling of mouse or key events.. because how else would you close the window!).

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

The only function that matters here is the changehp() function, and you didn't post it. Please do.

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

The strtok function:
"A null pointer is returned if there are no tokens left to retrieve."

You should handle that case. Possibly in your isValid() function (like a test for NULL before all the strcmp calls).

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

>>The nice way, however is to create a class 'Student' and overload the >> operator, but for now the above should do fine.

And the _easy_ way is to use std::getline() from the <string> header. As so:

string fullName;
  getline(cin,fullname);

that will capture everything until the return key is hit.

For your second question, just use std::vector instead of an array, as so:

vector<string> studentName(numberOfStudents);

You can access the elements just like you do for a static array.

thelamb commented: Not really sure how that slipped my mind... thanks +3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok. So, in my opinion, your best bet is to put the CheckCollision function right at the line 155 of the code you posted. In other words, after you have drawn to the screen and before you do the SwapBuffers call.

If it is not a convenient place to put it, and it probably isn't, you should use glReadPixels to capture (almost) the entire screen (i.e. the whole region of interest) and use that image for the collision detection.

BTW, glBegin/glEnd are deprecated, you should use VBOs in this day-and-age.

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

>>>>Report the first, 1000th and last elements in your sorted list.

>>It means, you need to sort the array, and print out the last 1000 items in the list.

No, I think it means to print the first, 1000th and last elements. Say you have a std::vector named "my_sorted_array", once it has been sorted, you need to have a printout statement as so:

std::cout << my_sorted_array[0] << std::endl   //print the first element.
          << my_sorted_array[999] << std::endl //print the 1000th element.
          << my_sorted_array[my_sorted_array.size()-1] << std::endl; //print the last element.

That makes sense, the prof can check that you have a correctly sorted array if those three elements are the same as what he gets from his solution program. (you can also check if your algorithm is correct just by using a simpler, easier sort algorithm or by using std::sort).

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

Line 115 should be moved to in-between line 117 and 118. However, the canonical (or idiomatic) way to do this kind of loop (from line 114 to 123) is:

for(it = theList.begin(); it != theList.end(); ++it) { //for all elements of theList
  cout << it->lname << " " << it->avg << endl;         //output the record to the terminal
  Outfile << it->lname << " " << it->avg << endl;      //save the record to the file
};

Much simpler, isn't it?

The same goes for lines 94 to 105:

while(!Infile.eof()) {       //while there are still elements in the file.
  Prog3.Read_m(Infile);      //read the values;
  theList.push_back(Prog3);  //add the record to the end of the list.
};

As others have suggested, there are more "advanced" ways to do these simple loops (with overloads, functionals, nameless functors, or lambdas), but that's not for you to worry about at this stage.

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

>>glReadPixels uses the pixels of the form.

Wait a minute... You cannot use glReadPixels to read from anything other than an OpenGL frame buffer. You must have created a Rendering Context (GL_RC) and be rendering all your stuff with OpenGL commands. If you are trying to read off a "form" as in a form from a GUI tool like Qt, MFC, or WinForm, then that will never work. You have to have a OpenGL window (an OpenGL rendering context (GL_RC) linked to a form's device context (H_DC), with everything rendered on an OpenGL viewport).

If you are using a GUI tool of some sort to display your image, then that GUI tool must have a function to read the pixels. That will probably be much easier to use.

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

Make sure that your glPixelTransfer parameters are properly set.

The glReadPixels reads the pixels from the frame buffer. If you are using double-buffering, make sure that there is something rendered on the frame buffer before reading from it.. and make sure it is the right one. For instance, if you render everything to the scene, and then you call glSwapBuffers, it is likely that after that point, trying to read pixels from the frame buffer will be useless because the frame buffer with all the rendered objects will have been swapped already.

I'm not sure how it works, I have never used this function. But I remember that I tried but never succeeded. Good luck.

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

If you read this doc, you will see that the width and height should be 1 if you want to read a single pixel. Second, the type parameter (which you have set to GL_BYTE) has to match the type of the pixel pointer which is GLfloat. So, that parameter should most probably be GL_FLOAT. Third, your variable pixel is an array, that means that "pixel" (without & or [0]) is a pointer to a GLfloat. So, you should omit the & sign in your code. Finally, if pixel is of type GLfloat, then the value of "white" is not 255 but 1.0. You could also just make your array "pixel" of type GLbyte (with the type parameter as GL_BYTE), which would give you 255 for full color (i.e. white).

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

>>I don't learn any thing easy, and it usually takes me a LONG time to learn and understand things
I had a friend who was just like that. He couldn't learn a thing without a _huge_ amount of explanation. Not so long ago, he went to a doctor and they discovered that a slight displacement of his jaw (probably due to a silly accident earlier in his life) had impaired the blood flow to his brain. Since they corrected the positioning of the jaw, he's a whole new person. True story.

If you think you might be suffering from a similar problem, a trip to the doctor might change your life. And I mean no offence by saying that, it's for your sake only.

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

Snake game! That's funny, that was (almost) the first program I ever wrote, it was on my TI-83 calculator (the first programmable thing I ever put my hands on), I was about 13 years old and I did it in a few days' worth of spare time. It was a nice game to play during those boring math lectures.

When WaltP said that it is impossible in native C++, he meant "native C++" as in the standard C++ libraries and STL (i.e. everything that is documented on www.cplusplus.com/reference ... oh, that's right, you're banned from that one). And he is right (of course!). Native C++ libraries don't handle screen display or async keystroke inputs, because that would put too much restrictions on OS designers.

For a minimalistic option, you can use systems like "curses.h" (for Unix-like systems) or "conio.h" (for windows command prompt) or "graphics.h" (for windows GDI, i.e. legacy Windows 3.1 stuff). But, more realistically, you should use something like win32 API or SDL.

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

Something that turns C++ code into machine code is called a "C++ compiler". How to show the machine code? Open an executable in a text editor!

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

The insert function is only if you want to insert an element at a particular position in the list. For regular insertions of elements (at the end or at the beginning), you use the functions push_back() or push_front() (for inserting at the end or at the beginning, respectively). Basically, most STL containers use a terminology akin to a queue or a stack ("push" to add, "pop" to remove). The insert and erase functions are for adding and removing an element at a specific position (positions are marked using an "iterator"). So, your file-reading loop should probably look more like this:

while(!Infile.eof())
  {
    Prog3.Read_m(Infile);
    theList.push_back(Prog3);
  }//while

NOTE: You are using a wrong wording in your question. I think you are confusing the concepts of a _class_ and an _object_. A class is the type (like int or double), while the object is the variable. So, in your code, Prog3 and temp3 are objects of the class cProg3. It's an important distinction to make.

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

You might want to use a debugger to trace the error. I don't know what IDE you are using but most of them are equiped with pretty good ones. Also, valgrind can help to detect and back-trace memory-related crashes.

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

This won't work:

~B ()  {
   for (int i=0;i<vec.size();i++)  { //size() is changing so this will not iterate through all elements.
      delete vec[x]; //what is x?
      vec.pop_front(); //why do you need to pop anything?
    }
   delete obj;
 }

I think this should work:

~B ()  {
  for (int i=0;i<vec.size();i++) 
     delete vec[i];
  delete obj;
}

If it is still crashing, it is not because of the above destructor. It is something else.

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

Well I'm not sure what exactly you want to do. To launch vlc, you just type vlc in the terminal. If you want to add a file (audio or video), you just put it as command-line argument to vlc. And, you can use "system" to write a command to the terminal. So here is a simple example:

#include <iostream>
#include <string>
using namespace std;

int main() {
  cout << "Welcome to VLC launcher program!" << endl;
  cout << "Please enter a filename: ";
  string filename;
  getline(cin, filename);
  string comm = "vlc \"";
  comm += filename + "\"";
  system(comm.c_str()); //call VLC with the file "filename"
  return 0;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Your problem is a nice situation in which the copy-and-swap idiom is very applicable:

class B  {
   std::vector<A*> vec;
   A* obj;
public:
   B () : obj(new A) {}
   B (int x) : vec(std::vector<A*> (x,new A(x))), obj(new A())  {}      

   B (const B& cpy) : vec(cpy.vec.size()), obj(new A(*cpy.obj)) { //notice the cpy.vec.size() here. no need to copy the vector, just construct a vector of the same size.
      std::vector<A*>::const_iterator o=cpy.vec.begin();      
      for (std::vector<A*>::iterator i=vec.begin();i!=vec.end();++i,++o)  {
         (*i)=new A(**o);
       }
    }
    
    B& swap(B& rhs) { //define a swap function, in terms of std::swap functions.
      std::swap(n,rhs.n);
      vec.swap(rhs.vec);
      return *this;
    };
   
    B& operator= (const B& cpy) {
      B temp(cpy); //copy the cpy object into temp
      return swap(temp); //swap this and temp. And temp will automatically be deleted.
    }  

   ~B ()  {
      for (std::vector<A*>::iterator i=vec.begin();i!=vec.end();++i)  {
         delete (*i);
       }
      delete obj;
    }
  
   friend std::ostream& operator<<(std::ostream& o,const B& b)  {
      return o << b.vec.size();
    }
 };

PS: It would really really make your life easier if you use smart pointers instead.

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

Yes, your implementation of the deep-copy constructor seems totally fine (as long as the objects a pointing to objects of class A and not of a derived class, like I said in a previous thread).

You probably want to also implement the assignment operator. operator = that is. Basically, it is almost the same implementation as your copy-constructor (in fact the idiom "copy-and-swap" or "copy-and-move"(C++0x) is a way to efficiently implement the assignment in terms of the copy-constructor. Or, you can just rewrite the same code again in the assignment operator.

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

>>'BinarySearchTree::{ctor}' : constructors not allowed a return type
If there is a return type, erase it. If there isn't a return type, then look at the code before the definition of the constructor to see if you made some mistake (like forgetting a closing bracket).

There are several subtle errors in your code. First, I think you have mixed up curPtr and curPtr->item at several points. I suggest you take a close rereading of the code with that in mind. My own, quick scan of it reveals several places where it is suspicious: Lines 75, 89, 93, 97, 165 and 200. Also, you have a single equal sign where there should be two at line 75.

Second, your destructor is not correct. In fact, it won't compile. You are deleting dereferenced pointers, when you have to delete the pointers themselves. So, to make it compile it would have to be:

BinarySearchTree::~BinarySearchTree()
{
  if (rootPtr != NULL)
  {
    if(rootPtr->leftChild != NULL)
      delete rootPtr->leftChild;
    if(rootPtr->rightChild != NULL)
      delete rootPtr->rightChild;
    delete rootPtr;
  }
}

However, this is still wrong because you are not deleting all the elements of the tree, only the top three nodes. Technically, you would have to traverse the tree down to the leafs and delete all the pointers on your way back up. However, the easiest thing to do is to write a destructor for the Node class that takes care of deleting its children (which will trigger a recursive deletion of the entire tree). …

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

Ok, well taken directly from the OpenAL Utility (ALUT) documentation. You can do the following:

#include <cstdlib>
#include <AL/alut.h>

int main (int argc, char **argv)
{
  ALuint sndBuffer, sndSource;
  alutInit (&argc, argv);
  sndBuffer = alutCreateBufferFromFile("my_sound_file.mp3");
  alGenSources (1, &sndSource); 
  alSourcei (sndSource, AL_BUFFER, sndBuffer);
  alSourcePlay (sndSource);
  alutSleep (1);
  alutExit ();
  return EXIT_SUCCESS;
};

And you are done. Just read the OpenAL documentation. It's all well explained in there.

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

>>The mean I got is 116.924 compared to the right one of 116.9404.
Well, that's not a very big difference. That's just accumulation of round-off error. It is not because your algorithm is wrong, but because it could be better. Basically, it comes from the fact that as you are adding and adding to total, it grows to a very large number. So, since the number of decimals that can be represented by a "double" is limited to about 16-20 significant digits, when "total" is very large, adding relatively small numbers to it no longer adds the correct amount because it is lost at the fringe of the precision of the variable (i.e. it gets heavily rounded-off).

One way to fix this is to use a recursive averaging formula instead. In other words, instead of accumulating all the pixel values in total and then dividing by the total number of pixels, you update an average value that is always roughly around the value of the pixel values. Here is how you could calculate the mean recursively, for a hypothetical vector v:

double average = 0;
int number_of_samples = 0;
for(int i=0; i<v.size(); ++i) {
  number_of_samples++;
  average = (average * (number_of_samples - 1) + v[i]) / number_of_samples;
};

Basically, you always take a weighted average of the previous average and the current pixel value. I guess the above formula is self-explanatory, and clearly yields the average at the end. Similarly, you can do it for the standard deviation. …

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

You know there is this minimalist programming language called brainf*ck which is a Turing Complete language (i.e. you can program anytime you like with it) and it has 8 operators and only 1 variable... a pointer! So, even the smallest programming language in the world has pointers!

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

I found this on HP docs (confirmed by MSDN too):

Identifiers

Identifiers are case sensitive and start with a letter (ISO Latin-1 decimal values 65-90 and 97-122), a dollar sign ($), a tilde (~), a colon (:), or an underscore (_); any additional characters can be a letter, digit (0-9), dollar sign ($), underscore (_), a tilde (~), a colon (:), or an operator symbol. Use of the dollar sign, tilde, and colon are extensions to C++.

I think the $ sign is a perfectly valid character for an identifier in C/C++, let alone a pre-processor macro.

EDIT: I still would not use the $ sign in an identifiers name, that's just too weird and any programmer reading it will automatically have doubts whether it does something special or not.

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

I have no idea what a $ sign does in a macro, if it even does something at all. As far as I know, the $ sign is not a reserved character and is not used for anything in C/C++, so I would imagine that it is a valid character to start a name with (especially at the pre-processor level). So, my guess would be that it was put there to signify that $Line is for the string literal code-line number (which is what the MACRO expands to, if you didn't know already). Is the MACRO used with or without the $ sign? If it is used with it, I'm guessing it is just that the name of the MACRO is "$Line". It's certainly weird, first time I see this.

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

try:

total += data[height * j + i];

I think that's the right one to use.
Also, I think that by default, the opencv OpenImage function will make the images into a color image (even if it was originally a grayscale image). So, if it is the default format, then you need to jump by 3 bytes (BGR) to jump from one pixel to the next. So this would be more appropriate:

total += data[3 * (height * j + i)]; //the 3 takes this 3 bytes stride into account.
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Line 49 is wrong for sure, it probably should be:

total += data[i*width + j]; //or maybe "data[j*height + i]"

At line 62, the ImageData array was never initialized, so it won't contain the actual pixel values, you should probably use data as above.

For the rest, I think you have it correct, both the mean and stddev.

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

I think for encoding and decoding, you can use libmp3lame from the LAME MP3 Project. I have never used it so I don't know how to use it, but I'm sure that the basic idea is to decode from mp3 to an uncompressed format and feed it through OpenAL (what SDL uses). I just saw that OpenAL now has an extension called AL_EXT_MP3 for playing mp3 files.

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

Well, on line 107, you have an assignment that should be an equality comparison (i.e. two equal signs). Besides that, the program I posted on my last post compiles perfectly well on a standard compiler (gcc).

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

You have to include the proper headers. For stringstream, it is #include <stringstream>. And for the getline, you need to include #include <string>. And it is not a mistake, the getline is not the one in the file stream class, it is a special global function that is defined in <string> to allow for string input from a stream.

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

With GCC, all you need is the -S option:

$ gcc -S my_program.cpp

It will create a file with the same name as the cpp file, but with extension .s and it contains the assembly listing (what you call machine language).

If you are not using GCC, then almost all IDEs have an option to either output the assembly listing and/or to display while in debugging mode. This is taken from an SO thread:

There are several approaches:

1.

You can normally see assembly code while debugging C++ in visual studio (and eclipse too). For this in Visual Studio put a breakpoint on code in question and when debugger hits it rigth click and find "Go To Assembly" ( or press CTRL+ALT+D )
2.

Second approach is to generate assembly listings while compiling. For this go to project settings -> C/C++ -> Output Files -> ASM List Location and fill in file name. Also select "Assembly Output" to "Assembly With Source Code".
3.

Compile the program and use any third-party debugger. You can use OllyDbg or WinDbg for this. Also you can use IDA (interactive disassembler). But this is hardcore way of doing it.

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

@AnnnDi: there are a few small problems with your program:
First, the srand() function only needs to be called once. So put one call to this function somewhere at the start of the program (either at the start of WinMain or at the OnCreate of your main form or something like that), and don't put another call to it anywhere else, it is not necessary.

Second, each time you call getSymbols(), it will generate a new random character. So you cannot call it once to print a random character to the Dialog and then call it again to do the comparison with the keystroke. You need to call it once, store the character that it gives, then put that character in your Dialog, and then reuse that same character in the comparison of the keystroke (you would probably have to make it a "global" variable... well maybe not global, but somewhere it can be reached by both the print function and the comparison function).

I think that should fix it, because I think you are doing everything correctly.

PS. Please ignore spoonlicker, _it_ is a troll.

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

**I couldn't watch the video, it requires SilverLight which I don't want to bother installing.

Off the bat, I would have to say that if you plan to make anything more complex than a few very simple GUI elements, just bare-bone Win32 API is probably not what you would want to use. Plus, it's definitely not cross-platform. Qt would be a much better option.

>>I'm really just wondering how to organize the window procedures for my Dialogs/Buttons/etc.
That is what Object Oriented Programming is for. Win32 API is kinda awkward to use for complicated interfaces because it's all procedural (C-style). The best you can do is wrap those API calls into sensible classes. Often, you can just reflect the underlying structure. When you create Window, you get a HWND handle (which is most probably a pointer to an object that was created by the windows library) and only a set of functions can use this HWND. Well, naturally, you can just create your own class that has an HWND as private member, and whose constructor/destructor create and destroy the Window, for example. Doing this will make it a lot easier to use after... but the problem with that, is that it is a lot of work, and that work has already been done for you in countless GUI tools like Qt, wxWidget, MFC, VCL/CLX, etc. You would definitely be better off, in the long run, to get used to one of those.

>>Would one normally after …

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

This line is the problem (line 18):

inFile.read((char*)&Value1, sizeof(string));

You have to understand that string is not like primitive types (like int or float or char), it is a class. This means that an object of class string is not as "simple" as a primitive type. So, simply casting it to a char pointer and writing to it is not going to work. Internally, the string class probably stores pointer to a chain of characters, and when you do this cast and write operation, you are overwriting that internal pointer with some values from the file (you are not filling in the characters). This makes the pointer invalid, and when it is time to delete the string object, the code calls delete on an invalid pointer and you get a crash (access violation).

There are special functions to handle input/output with strings, read() should not be used (unless you are writing a predetermined number of characters to a char array, not a string object). Assuming that the string is contained in your file as a null-terminated string, then this function would be appropriate:

getline(inFile, Value1, '\0'); //this will fill Value1 with characters from inFile until a null-character is found.

If the end of the string is marked by another character besides the null-character (perhaps a newline) than that is the character you put as the third parameter to getline().