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

I guess you could start from a tutorial example (from msdn or somewhere else), just copy/paste the code and start tweaking it, that's the easiest way. Then I guess you will need two programs, one that sends (or at least initializes the communication) and one that receives. Or what you can do to start is to make an "echo" program that simply outputs back whatever it receives. Then use a terminal application to type in strings to be sent to through RS232 (like Term, TERMINAL, Termite, etc.) and see if you get the echo back. Then, start tweaking to parse the commands and stuff.

It might be easier to use std::string and related functions instead of strcmp() for string parsing and comparison. If you want to be real fancy you can use boost::tokenizer or boost::spirit/lambda/phoenix, but these require quite good understanding of C++ to use (template meta-programming).

Basically a RS232 communication usually goes something like this:
- Open Port... check that it worked..
- Configure... [optional]
- while ( some_flag_that_means_the_program_is_still_running ) {
- while( readFile(...) == PORT_EMPTY ) { //PORT_EMPTY is made-up.
- sleep( some_small_time_interval );
- };
- Process received value (usually a string);
- if ( received_command == PROGRAM_TERMINATE )
- some_flag_that_means_the_program_is_still_running = false;
- };
- Close Port (closeFile())

Basically that is how the Win32 API is setup to work. But I'm sure there are libraries that make serial port communication a bit …

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

Use a mutex to protect the access to vector. Mutexes are your best friends in multi-threading. A mutex (short for "mutual exclusion") is a thing that is supported by all multi-threading-capable operating systems (the API functions to use may change depending on your OS). What it does is that it allows one thread to lock the mutex while it's accessing memory in vector (read or write or both, doesn't matter). While the mutex is locked to one thread, it cannot be locked by another until it is released (or unlocked) by the thread that owns the lock. So if a thread wants to access the vector while another thread has a lock on it, it will be blocked (suspended execution) until the mutex is released and then it will lock it for itself and do its own operations on the vector. In code, using boost::thread library (which I recommend for that purpose, but others are similar):

vector<int> v; //say you have a global vector v of integers.
boost::mutex v_mutex; //create a global mutex for it.

int getValue_ThreadSafe(int Index) {
  //lock the mutex at first, if already locked, this will suspend execution until it's available.
  boost::unique_lock< boost::mutex > lock_access_here(v_mutex);
  //return the value and "lock_access_here" variable will go out of scope and release the lock on the mutex.
  return v[Index];
};

void push_back_ThreadSafe(int NewValue) {
  //Again same procedure..
  boost::unique_lock< boost::mutex > lock_access_here(v_mutex);
  //push_back, return and thus, release mutex lock.
  v.push_back(NewValue);
};

Other mutex implementation beside boost::thread exist of course, but this …

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

First off, the line "TicTacToe game(char X,char E);" actually is interpreted by the compiler as a function declaration, so that is what the error message points. "game" is declared as function, as far as the compiler can tell. In any case, this is not valid syntax, as Dave pointed out. You cannot declare variables X and E in the constructor call (or in any function call).

Second, the call "game->displayBoard();" should be "game.displayBoard();" because game is an object (if it was correctly constructed) and not a pointer (that requires this "->" syntax, as dereferencing operator).

Third, your use of "char" is not proper to identify the player. Declaring two char variables called X and O does not make them hold the values 'X' and 'O'. So forget the line "char X, O;" in your class.

Fourth, you need some initialization of your class, you need an implementation for your constructor. I would suggest you initialize the values of "board" to its index characters, e.g., "board[0] = '0'; board[1] = '1'; ..". Then you need to offset the value you read as "box" such that a character '1' because an integer value 1, or you can make "box" an "int" type (that's much easier).

Finally, adding a function to check if someone won the game after each move would be nice.

Do 1-4 and you should be able to compile, or at least it will be improved quite a bit. But you're right, the logic is …

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

Yet another alternative.. maybe a bit of overkill or too advanced but if you want to implement this is the future again in a robust manner, you should know this thing you are probably trying to do here is called a "singleton", at least from reading between the lines of your original post. So a typically more robust solution that avoids global scope extern variables (which are pretty much not allowed on bigger projects):

// main.hpp
class Foo { .. };

Foo* getGlobalFoo();

// main.cpp

Foo* getGlobalFoo() {
  static Foo my_foo(.. some initial value ..);
  return &my_foo;
};

// other.cpp
#include <main.h>

void Bar() {
  Foo* global_foo = getGlobalFoo();
  ... use global_foo ...
};

I personally use a variation of that and it is really robust, never had any problems with it. There are advanced issues that probably out of scope of this thread that this scheme prevents better than the alternatives.

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

I agree with Stu, you need to post some sign of an effort.

Just a start-up idea, use a function (method) to compute the square-of-the-distance between two points (as in a method of class "point"), and you can pretty much use it for all the other methods.


@StuXYZ: you should add to your quote "experience is the most expensive way to learn anything, but it's the only way"

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

Well \ is a special character. C++ still caries the remnants of C formatted strings, for good reason. So "\\" actually means the single character "\" and "\" or '\' is an error. This is because you use \ to enter special characters like '\t' for tab, '\n' for newline, '\r' for carriage-return, and some others too. You have to understand that searching for '\' to replace it with '\\' is not going to work. Although a string might be displayed on the console as a single '\' it will actually be represented in formatted string format as '\\'. If you want to search for the single character '\', you have to search for the _single_ character '\\', it sounds confusing but that's how it is.

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

Point taken! I agree very much, I just sometimes feel a few lines of code can explain better than a whole bunch of writing. It's just that C++ is a more natural language for me to explain stuff than English.

I'll be more diligent about that in the future.

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

Well, I have more than 12 years of experience in OOP programming and I started as a teen with 3D game programming (now doing more multi-body dynamics simulation, robotics control software and artificial intelligence). I jumped right into OpenGL from the start and painfully rammed through it all. I recommend being a little more cautious but still 3D gaming is exciting and it's hard to go slowly once you get a few things running. One link I highly recommend to learn openGL is http://nehe.gamedev.net (it is where I learned and all my friends in the gaming industry too, awesome tutorial, simple, clear and detailed).

How much C++ do you need? Well, you can start programming games from knowing nothing or you can start after having a Computer Science degree (which really won't make that big a difference to be honest). That I know of, there is only one way to learn, that is practice, practice, practice... It seems you understand that you can't just read books and expect to be a good programmer (as you say you practice a few hours every day). Personally, I have had many little projects one after the other, making a game engine, then a physics engine, then a better game engine, then a 3D model editor, then a particle system, then a better physics engine, etc. etc. I think now I have iterated to my 5th or 6th completely new physics engine (or now multi-body dynamics simulator) and about the same …

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

1. Initially the constructor has its own allocated memory (which sizeof(string*) + 2*sizeof(int), for arr (pointer to string) and numAllocated and numUsed (two integers)), then the constructor itself allocates memory for two string objects (size = 2*sizeof(string)). I cannot tell you how big each of there are because that is OS and PC specific, so for your environment, you can simply check it but writing a simple program which calculates the above two sizes, if you really want to know. But knowing the exact size is useless since you really cannot use it because the standard does not guarantee it in any way.

2. For the null-character stuff, this is internal to the class "string" and thus I have no idea and in 12 years of programming I have frankly never cared about it. This is what is called "abstraction" in C++.

3. The strings are stored in memory one after the other, but each "string" object holds some pointer to the actual character sequence (probably null-terminated, or not, again I don't know and I don't care, and so should you, because it is meant to be abstracted away from whoever uses class "string"). So to answer the question, to access a character of a string you do arr[1][2], for the third character of the second string in the array.

The above implementation is called a dynamic array because it allocated memory by a factor of 2 every time more space is needed, this highly reduces the …

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

Well, as a robotics engineer, I can tell you that hardware programming is far from obsolete. It is in fact probably the most important and time-consuming task when dealing with robots and other similar stuff.

One thing that is important with hardware programming is what you are programming on. If it is a standard PC and your hardware is via USB, RS232, FireWire, etc. than you will have to resort to OS-specific libraries (but mainly standard parts of the operating system libraries) and this is really like regular programming but often these OS APIs are based on C, but very easily wrappable in a C++ environment (the so-called hardware interface layer of your program).

If you're dealing with a embedded PC or microcontroller (which simple robots, mobile phones and other small stuff use), then you have to check if it is powerful enough to run an operating system like FreeRTOS or micro-Linux (or embedded windows if you are of that painful OS flavour). Then there is a whole bunch you need to look at for so-called "cross-compiling" in order to write, compile and test your programs on a PC. There are editors tailored for that, like AVR-Studio and Arduino, most of which allows you to program in C++, but the standard libraries (std namespace) require that you have the appropriate libraries for the system you use. Often micro-controllers offer only C run-time libraries, but if you can run an operating system than it usually comes with all the …

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

Your call to "cin >> phrase" will by default copy the string before the first space character. Just replace it with "cin.getline(phrase,1024,'\n');" and it will work.

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

I didn't think this was a course exercise...

If it is an advanced exercise, they should allow, it is part of the new standard extension TR1.

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

This is how:

...
int main (int argc, char** argv) {
  //read name into dymanically allocated array
  string filename = "names.txt";
  if(argc > 1)
    filename = argv[1];
  ifstream names(filename);
  if( ! names ) { cout << "error reading names"; exit(1); }
...
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ohh so you have a file with each question on separate line.. then it all becomes so much easier. Just change "string questions" for "vector<string> questions" and replace the call "questions.append(...)" by "questions.push_back(...)". Then your function can return a "vector<string>" and you will have your array (or vector) of questions.

So to print one question simply call:
cout << questions[current_question_index] << endl; //or insert a "?" if the question mark is missing from the question string.

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

yeah.. cin is a class, sure, that receives the character streaming from a buffer. You're right, you can't flush it, because only the writer of a buffer can flush it (computer science 101), that was my point. Only the user can trigger flushing of the input buffer so there is no way for you in the program to try and flush it, you can only wait for the user to do an action that the operating system (or terminal / console application) will deem worthy of a flush, like pressing <enter>.

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

Assuming for simplicity that the trivia is Jeopardy, and answers are separated by '|':

string answers = "42|George W. Bush|Burt Reynolds|Edmund Arantes Do Nancimento";
vector<string> answerArray;

int last_delimiter = 0;
int current_delimiter = answers.find('|',last_delimiter);
do {
  if(current_delimiter == -1) {
    answerArray.push_back(answers.substr(last_delimiter,answers.size() - last_delimiter));
    break;
  };
  answerArray.push_back(answers.substr(last_delimiter,current_delimiter - last_delimiter));
  last_delimiter = current_delimiter + 1;
  current_delimiter = answers.find('|',last_delimiter);
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First, I recommend you use a boost::shared_ptr for all "next" pointers and a boost::weak_ptr for all "prev" pointers, this will allow you to get rid of your destructor altogether.

Second, you should think whether you really need a copy-constructor for your queue. If you don't need it, make the class non-copyable (making the copy-constructor and assignment operator private with no implementation). This will get rid of the rather messy copy-constructor you have.

How do you hold a pointer to head? well you hold a pointer to head, that's all. You have to hold some starting pointer somewhere, either head or tail or both.

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

I don't understand how "gradez = grade[] + 1;" is supposed to "try to match what letter grade the user typed". This makes absolutely no sense to me!

well, doing "gradez++;" will effectively turn an 'A' into a 'B' and so on. I guess that line was mistyped on this forum post.

With that I don't see anything wrong really. If gradez does not come out well maybe you can try the cin.getc() function instead. And possibly the "cout << gradez" outputs in decimal instead of as a single character string.

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

Wow... your prof. seems to be a d'bag. Not to mention that this is probably the worst possible way to implement a sparse matrix class. And it doesn't seem like your prof has much of an idea about C++ programming.

Anyways, the explanation is very vague, but from what I understand of the problem, this is what I can say. First, the problem says "implement the following methods:..", this means all the functions that you have there should be methods, i.e., member functions of class "valuenode" for most and some for "sparse".

Second, the struct "valuenode" is also templated. I'm not sure if it needs "template<..>" before its declaration but it certainly needs it when declaring pointers "valuenode*", it should be "valuenode<T>*".

Third, you need to figure out what the prototype of theses methods are supposed to be. I'm guessing "prev_row_entry()" should return the valuenode pointer to the previous row. All these are pretty simple. Then the others, like "get_entry" and things might involve some hopping through the linked list (custom iterators if you want to be fancy). Really, implementing stuff as linked list is really not that hard, you just hop from one node to the next instead of incrementing an index.

Essentially, this problem is like implementing a "std::list" class, so look at that standard class, its methods and iterators to understand what your prof wants you to do but in 2D (rows and columns) instead of "list" which is only linear.

Frankly, …

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

If your assignment is for a C++ course, you better do this instead of the above:

std::vector<std::string> questionArray;
questionArray.push_back("This is question 1");
questionArray.push_back("This is question 2");
questionArray.push_back("This is question 3");
questionArray.push_back("This is question 4");

Your prof. or corrector might not be too happy to see C-style code in a C++ course assignment.

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

you're not outputting values f[0] and f[1] before entering the loop.

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

Well.. "circular referencing" are you doing something weird like including the cpp in the header and than including the header in the cpp without guards. Or something like that with other source files.

So, you should add a guard to your header file.. a guard means putting as first lines in your header:
#ifndef MY_HEADER_FILE_HPP
#define MY_HEADER_FILE_HPP
Or some other unique name. Then finish the header file with one "#endif"

The child ... part I think is a problem with MinGW and Windows 7. At least by a google search of "died before initialization with status code 0x1" I get tones of results that say it is a MinGW problem with Vista and later versions of windows.

PS: USE LINUX!

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

You should clarify what you mean either "read from an array" or "write into an array"... I'm not sure which one you mean.

If you have a string that contains all questions.. then I guess you have to do a for-loop for each character until you hit a '?' character and take the string before and including the ? and append it to the array, then continue with the rest of the string until there is nothing left. At the end you will have an array. You can use "std::vector<std::string>" for the array and "insert()" to add and operator [index] to get a question in particular. Well.. I'm sure you will want to use a struct or class that holds the question string and the right answer string too.

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

But still..
this is more efficient:

double point::distance(point cord)
{
  return sqrt((double)((x-cord.x)*(x-cord.x)+(y-cord.y)*(y-cord.y)+(z-cord.z)*(z-cord.z)));
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well.. the error is very strange.. never seen that before. But the source of it is very easy to find:
Your first two functions have a ";" before the opening braces! Two weird errors, two misplaced semi-colons.

Also, where is the implementation for your constructor?
And, you should not use "pow()" function, it is much more efficient to just multiply them out for a simple square power.

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

Well.. if the dictionary is in a file and in alphabetical order, then a binary search would probably be good enough. But if you deal with a database (which I recommend), then those search algorithm are included in the database server (MySQL, or any other you have access to) so all you have to do is say "find <first_characters>*" and it will find everything that start with your first characters (look up SQL query language for more details on that). You can be pretty sure that the search algorithms in the database is far more efficient than you could ever program yourself (there are people who make a living at perfecting those search algorithms).

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

@coolzinthis this is pretty straight-forward:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

struct Person {
  string first;
  int votes;
};

int computeTotalVotes(Person* candidates, int count) {
  if(candidates == NULL) return 0;
  int sum = 0;
  for(int i = 0; i < count; i++)
    sum += candidates[i].votes;
  return sum;
};

void printCandidateResults(Person* candidates, int count, int totalVotes) {
  cout << "Candidate Votes Received % of Total Votes" << endl;
  cout << "---------------------------------" << endl;
  Person winner;
  winner.votes = 0;
  for(int i = 0; i < count; i++) {
    cout << candidates[i].first << " " 
         << candidates[i].votes << " " 
         << 100.0 * ((float)candidates[i].votes) / totalVotes << endl;
    if(winner.votes < candidates[i].votes)
      winner = candidates[i];
  };
  cout << "---------------------------------" << endl;
  cout << "Total " << totalVotes << endl;
  cout << "The Winner of the Election is " << winner.first << "." << endl;
};

int main () {
  //read name into dymanically allocated array
  ifstream names("names.txt");
  if( ! names ) { cout << "error reading names"; exit(1); }
  int count = 0;
  names >> count;
  Person* p = new Person [count];
  for ( int i = 0; i < count; i++ ) {
    names >> p[i].first;
    names >> p[i].votes;
  };

  int total = computeTotalVotes(p,count);
  printCandidateResults(p,count,total);

  delete p;
  return 1;
};
Fbody commented: Don't reward irrelevant bumps. Especially by not following the posting guidelines. +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First of all, you need some kind of GUI for this, cin / cout won't be good enough for sure (or a least a lot of trouble). So figure out what you want to use first (Qt, MFC, SDL, whatever..), then you can start to solve that problem.

Second, I'm sure there are already some tools for Qt or MFC that do this.

Finally, yes you will need a database or something to get a dictionary. These would be OS-specific and package-specific (linux). I can't help you much further with that. If you are up for it you can check something like KSpell (open-source spell-checker for linux, takes words and matches them to a dictionary to give suggestions if an exact match is not found), but I presume the source-code will be large.

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

First of all, inventory should be initialized to contain at least one element for case A (otherwise inventory.begin() is pointing nowhere) and at least two elements for case B,C,D.

Then, you have to understand that an iterator is essentially a pointer (not exactly, but it behaves like one), so setting it to one, if it was allowed by the compiler, which it most certainly does not, would make your iterator point to memory location 1 which is completely meaningless. So you must understand that an iterator is not an index in the array but more like a pointer to an element in the array.

Finally, since iterators are not pointers because they can have more complicated behavior, although in the case of "vector" it is pretty much just a normal pointer, they cannot be assigned to a pointer, so even sending "&inventory[1]" to the insert function will not work because you cannot convert a pointer to an iterator.

You should be more careful when using iterators and arrays and stuff. Look at the documentation (www.cplusplus.com or somewhere else) about each function you use and make no assumptions (like that "myIterator = 1;" is correct!) before you double checked it in the standard documentation. A lot of the above errors will not be caught by the compiler, but not all, and those that are not caught will cause "undefined behavior" which is an expression to remember and look out for when programming in C++ or any …

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

cin is a buffer, it needs to flush, just like cout. There is no guarantee that cin will flush every time you press a key but it is guaranteed that it will flush when you hit enter (just like cout is guaranteed to flush when you write std::endl or "\n"). That's why it will freeze until you press enter, but it could also unfreeze earlier when you have typed something but not hit enter yet (this rarely occurs but it can, like if you type a few letters, then minimize the terminal window and maximize again, this could trigger cin to flush the few letters you had typed before and unfreeze execution). For instant key-stroke detection you need OS-specific stuff or a GUI platform of some kind. Cin is meant for command-line instructions: basically, "type a command and press <enter>".

BTW cout is independent from cin so waiting for a char or string input from cin will not freeze cout, but it will freeze execution of the calling thread. In the mean-time, another thread can output anything to cout and it will never show up in cin because although they share a terminal they are separate buffers. So the console is not freezed, your program is, as long as you have only a single thread.

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

You should find out where this error occurs:
Is it before writing the first chunk? -something wrong with init.
Is it right when you switch to second chunk? -something wrong with the switch.
Is there anything special about the point at which the error occurs (middle of a chunk or at a switch, and which switch)? -something is winding out of scope.
Or does it occur at random times? -thread synchronization issue, almost certainly.

So check to make sure your writing operation is not going beyond the current buffer (in my experience, problems like that are usually due to a little typo somewhere).

I assume this is multi-threaded (one thread pushes, the other pops), so make sure to use a mutex to protect the buffer, especially during the switch.

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

I think this thread addresses the issue very well:

http://bytes.com/topic/c/answers/774079-end-stream-std-cin

Simply put, the std::cin will not reach end-of-stream until the user presses ctrl-D or kills the app. From the last example on the previous post, it is pretty clear why it doesn't make sense for eos to be reached unless the app is about to die, because the user can always enter characters until that point or until he detaches the terminal from the app.

Agni commented: thanks !! +3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I see first that a lot of these examples use integer delimited with spaces, and newline triggering the end-of-stream. But in your example end-of-line delimits the strings by default, but what triggers the end-of-stream? should it be set as format for std::cin? Is it OS-dependent?

In other words if newline is used to delimit strings that are captured by the istream_iterator, then every time you hit enter you will get a new string captured and outputted in std::cout, but there is no way for the computer to know what enter-strokes mean "put a new string" and which mean "end the program or string capture". This is really what copy does and I tested and it behaves exactly as your program:

std::istream_iterator<std::string> Iter(std::cin);
  std::istream_iterator<std::string> eos;

  while (Iter != eos) {
    std::cout << *Iter << std::endl;
    Iter++;
  };

There is not exit condition because no action from the user can trigger eos. It would make this bizzarely impossible:

{ 
  std::istream_iterator<std::string> Iter(std::cin);
  while (Iter != eos) {
    std::cout << *Iter << std::endl; Iter++;
  }; };
  {... do something ...}
  { 
  std::istream_iterator<std::string> Iter(std::cin);
  while (Iter != eos) {
    std::cout << *Iter << std::endl; Iter++;
  }; }; //PROBLEM: std::cin has already reached eos, so input cannot resume!

But this is just my humble opinion, a better expert is needed for istream related stuff. I usually isolate cin in my apps with a kind buffer class of my own.

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

I think C++ can be hard at first.. a good way to ease into, if you already have some experience with C or other simple procedural languages, is to just keep programming in C but compile in C++ and slowly change you habits from printf to std::cout, from malloc to new, from struct to class, from function to methods, from pointers to references, from init functions to RAII... and before you know it you will be digging into object-oriented programming concepts and it will take-off from there.

Personally, I would say that C++ might be hard to learn, but once learned it's hard to stay away from it, every other language just seems pale in comparison. There is a huge amount of details to know about the language but it's very progressive in the sense that you can quite quickly learn the few things you need to be functional and be able to do anything you want to or need to do, but it might take many years before you become a programming beast without comparison to any programmer from another language.

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

This site was not mentioned yet, but I like it a lot for all the small details you might overlook while coding but that often are hugely important:

http://www.parashift.com/c++-faq-lite/

It nicely written and cover a plethora of issues from very simple to very complex.

Lusiphur commented: Thanks :) Added to bookmarks +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@Agni, you're totally right, I'm sorry, from the looks of the problem it seemed like a sort of basic programming class exercise (you know, do a simple looping algorithm and output to the terminal, that's classic). But of course if it is part of a bigger project or something then <algorithm> is fair-game of course and a time-saver.

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

Well from what I know if you use shared libs (as it is stated there) than don't expect your library to be completely statically linked.. it is not dependent on how you compile or link your code but how the libraries you use are made. As simple as that. A compiler cannot and will not "import" code from shared libraries to put it in your binary such that all external binary dependencies vanish... still your library can be statically linked to any application that are compiled to use it and then the remaining dynamic links for the application will be those of your static lib and any others... this is unavoidable, as far as I know. Learn to live with it, minimize external dependencies and use static standard libraries only if you want to avoid trouble with having to ship your applications with a bunch of dependencies on installation.

Check if your gcc is set to take static libraries for the standard C++ libraries and not shared ones (which I doubt), as I assume hello.cpp in this case is very simple, that would be the only reason why the compiler could not statically link everything.

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

You can do a C-style cast (although the compiler will complain) or a reinterpret_cast of the pointer to one with no const restriction. Or as Agni said, just make it mutable.

One thing that ticks me though... you say "I have a const-correct method".. well putting "const" at the end of the declaration does not make it const-correct, it is not violating that constraint in the implementation that makes it const-correct. Of course const-correctness is a strict rule for those who follow it, you can make the choice not to be const-correct in your code.. but if you do you might run into programmers like myself who are not willing to use open-source code that is not const-correct because it pollutes the open-source software eco-system.

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

@Agin: I think using generic algorithms goes against the purpose of the exercise..

First, a simple trick is to use a magic number like 0 or MAX_INTEGER or something to mark the already matched values as invalid, then check that a number is valid before looping for matches.
Second, the second loop (match search) only needs to start from i+1 because all previous values have already been looked at as a.

//set some magic number.
#define INVALID_VALUE -43425234 

{..}

for(int i=0;i<max;i++) {
  if(a[i] == INVALID_VALUE)
    continue;
  count=1;
  for(int j=i+1;j<max;j++) {
    if(a[i]== a[j]) {
      count++;// count houw many inegers are the same
      a[j] = INVALID_VALUE;
    }
  }
  cout<<a[i]<< " = "<<count<<endl;
  count= 0;
}

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

the copy() function will try and increment the iterator on std::cin until it finds this null istream_iterator (which I doubt is a correct use, but I'm not so familiar with this class). The problem is that std::cin is special in the sense that every time to increment the iterator it will wait for a new line before outputting the new iterator. In other words, it can not test that the new iterator is eof or null or whatever until you enter a new line, and then it is not "invalid". So that's why this code is endless. And philosophically speaking, how can the program tell when the user is done inputting stuff? Unless you set some real end-condition, the copy() function will not guess it.

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

Why not use an embedded accessor class:

class PersonalInfo {
  private:
    int ID;
    string Name;
  public:
    struct Accessor {
      int& ID;
      string& Name;
      Accessor(PersonalInfo& Host) : ID(Host.ID), Name(Host.Name) { };
    };
    struct constAccessor {
      const int& ID;
      const string& Name;
      constAccessor(const PersonalInfo& Host) : ID(Host.ID), Name(Host.Name) { };
    };

    //...
};

I use this sometimes. It's a nice way to avoid declaring a bunch of friend classes while making sure to require a little bit of extra work for the user-programmer to access private members. It makes sure the user-programmer does it on purpose and