Narue 5,707 Bad Cop Team Colleague

and because i wanted derived classes to use these variables i had to define them outside of the base class to override the scope of the variables

That has nothing to do with scope. The visibility of your static members in derived classes will be determined by the access modifier (public, protected, or private). A definition is expected outside of the class for the compiler's benefit. Rather than require compilers to implement complex logic for ensuring that only a single definition of the member is created, that requirement is delegated to the programmer, who's in a position to do it properly and without difficulty.

Narue 5,707 Bad Cop Team Colleague

Now you need to define them. :D Add the following to base.cpp:

IMesh* CBase::PlayerMesh = 0;
IModel* CBase::Player = 0;

For non-static data members, the constructor will define them as a part of the object. For static data members, that's not practical, so unique definitions need to be provided separately.

Narue 5,707 Bad Cop Team Colleague

I notice that those data members aren't static, and thus aren't shared between objects. Each object you create gets its own completely separate copy of non-static data members.

Narue 5,707 Bad Cop Team Colleague

Can you post a short code example of what you're doing?

Narue 5,707 Bad Cop Team Colleague

any idea what sort of cryptography that might be?

The zero padding suggests a block cipher of some sort. If you're trying to generate passwords that are accepted by the game or decrypt passwords from the game, you're looking at some serious cryptanalysis. Not only do you need to figure out the algorithm the game uses, you also need to determine the key(s), salting schemes, initialization vectors, and pre/post hashing. If the game uses anything remotely strong, it's probably going to be an impractical venture.

Narue 5,707 Bad Cop Team Colleague

Your prototype of fun says that sum and avg are floats. Your definition says that sum and avg are pointers to float. Make up your mind.

Narue 5,707 Bad Cop Team Colleague

I don't understand what is wrong with writing code like: Wood a, b, c; (a * b) = c;

There's nothing wrong per se. It's generally frowned upon because when overloading operators, the general rule of thumb is "do as the ints do", or match the semantics of built-in types. If the same operators have different semantics on your custom type than they do on built-in types (or standard library types), you make understanding the code more difficult.

Fbody commented: Good rule of thumb. I'll have to make sure I remember that one. :) +5
Narue 5,707 Bad Cop Team Colleague

I've seen the term used in two contexts:

  1. An algorithm for an undecidable problem. In other words, there's no proof that the algorithm will reach a conclusion in finite time.
  2. In reference to hypercomputation theory.
Narue 5,707 Bad Cop Team Colleague

Couldn't they have just used size_t instead?

Sure, but there were two reasons to define size_type:

  1. Support custom allocators and different memory management strategies without forcing code changes.
  2. Historically, size_type was added to the STL implementation to deal with a problem on the Intel architecture (no, I don't know what the problem was).

Though if you're using the standard allocator, size_type and size_t are synonymous.

Narue 5,707 Bad Cop Team Colleague

ICU is enormously complex because Unicode is enormously complex.

when all I need is a number to character and back again conversion?

Let's assume you want to do it manually. You'd need to support at least UTF-8, UTF-16 (including surrogates), and UTF-32. The process is different for converting each of those into a code point. Now, in all honesty that's not especially difficult. It's more difficult than calling a library function, but straightforward, in my opinion.

The hard part comes when you realize that you're probably not just converting a character to a code point, you're likely introducing general Unicode support including I/O and comparisons, which opens up a can of worms like normalization (and normalization is stupidly complex if you're thinking about doing it manually).

Narue 5,707 Bad Cop Team Colleague

what do I exactly achieve?

The clear member function clears the error state, which is set when cin encounters an unexpected character. If you don't clear it, you won't be able to read anymore characters from the stream.

I read is equivalent to what you Narue used

It's only equivalent if the implementation defines streamsize as int:

typedef int streamsize;

But any assumption that depends on an implementation decision is not portable. Your way is unlikely to cause a problem, but it's not strictly correct in that streamsize could be defined as a larger type and the contents of the stream could exceed the maximum size of an int, in which case the call to ignore wouldn't discard the contents of the streambuf.

I believe what it does is to discard the input up to the maximum int input, is it correct?

Up to a count of the first argument, or until a character matching the second argument is found. The equivalent loop (greatly simplified) is as follows:

int n = INT_MAX;
char c;

while (--n >= 0 && cin.get(c) && c != '\n')
    ;

what about #include <ios>?

<ios> is where std::streamsize is defined.

I suppose we validate only the first character, so If I input something like 4a, it will accept it as valid woudn't it?

It'll read and validate until whitespace or the conversion fails. So yes, if you input "4a", it will accept 4 and leave "a" in the stream. That's …

Narue 5,707 Bad Cop Team Colleague

If this is a serious project (as opposed to something for learning Unicode), I'd suggest ICU. Managing Unicode is a bitch without a good library.

Narue 5,707 Bad Cop Team Colleague

The easiest way to validate addBalance is to get user input as a string instead of int.

That's only easy on the surface. Sure, you can check that every character is a digit, but that still doesn't guarantee a successful conversion to int. If you're going to defer to a library for the actual conversion, assuming you select a library that isn't stupid, a more robust validation will be done internally anyway.

In your code, stringstream already does this, so the manual validation prior to using stringstream is both redundant and incomplete.

Narue 5,707 Bad Cop Team Colleague

All of the is* functions accept an int type, but the range must either fit into an unsigned char or equal the EOF macro. In this case, you can use cin's status to determine validity:

#include <iostream>
#include <ios>
#include <limits>

int main()
{
    int amount;

    while (!(std::cin>> amount)) {
        std::cerr<<"Invalid amount. Please try again: ";
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }

    std::cout<<"Valid amount: "<< amount <<'\n';
}

It's not perfect, but robust stream I/O is surprisingly difficult.

Narue 5,707 Bad Cop Team Colleague

>while(!text.eof())
This is an off-by-one error because eof only returns true after you've attempted to read beyond end-of-file. So you'll have one final iteration of the loop where get fails, but you still process b (from the previous iteration). You can use the result of get as a condition, which is both correct and more concise:

while (text.get(b)) {
    // ...
}
Narue 5,707 Bad Cop Team Colleague

How is that "just plain stupid"? It looks fine to me. Of course, there are other ways to do it, but fscanf would work just fine.

If the input is guaranteed to have four words separated by '$', then an integer, it'll work fine (in an ugly way), but the example string doesn't strike me as strictly formatted, in which case fscanf would be a bad idea. What happens if another word is added, or a word is removed?

Narue 5,707 Bad Cop Team Colleague

This is more of a job for something like strrchr. Assuming you have the line in memory already:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    const char *line = "This$is$my$Input$203";
    const char *start = strrchr(line, '$');

    if (start != NULL) {
        /* Error checking omitted for brevity */
        printf("Found %d\n", (int)strtol(start + 1, NULL, 0));
    }

    return 0;
}
Narue 5,707 Bad Cop Team Colleague

I think you'd be well served by drawing the whole process out on paper, or perhaps with a handful of change (I use the latter often when working with data structures). It'll help you visualize what needs to be done, and you'll be able to get a better feel for the steps.

Narue 5,707 Bad Cop Team Colleague

One big decision you need to make in merging is whether it's destructive or not. Are you going to remove nodes from each list and add them to the result, or copy the data into new nodes?

Either way the merge works as a traversal. Select between the two lists based on some useful ordering as long as both lists are not empty. Only the selected list is moved forward. Once one list becomes empty, unconditionally copy the remaining list to the result. Consider the following:

node *merge(node *a, node *b)
{
    node *c = 0;

    while (a != 0 && b != 0) {
        if (a->info < b->info) {
            c = insert(c, a->info);
            a = a->next;
        }
        else {
            c = insert(c, b->info);
            b = b->next;
        }
    }

    while (a != 0) {
        c = insert(c, a->info);
        a = a->next;
    }

    while (b != 0) {
        c = insert(c, b->info);
        b = b->next;
    }

    return c;
}
Hojjat.Mojallal commented: It solved my problem +0
Narue 5,707 Bad Cop Team Colleague

The text box control uses Windows newlines for line breaks:

infotxtbox->Text = "Name: Peter Jaško\r\n"
                   "Rank: Main Tech Manager, Vice-Leader,\r\n"
                   "Donated: ?,\r\n"
                   "Exp: ?";

Though the "proper" way to do it is with Environment::NewLine:

infotxtbox->Text = "Name: Peter Jaško" + Environment::NewLine +
                   "Rank: Main Tech Manager, Vice-Leader," + Environment::NewLine +
                   "Donated: ?," + Environment::NewLine +
                   "Exp: ?";
Narue 5,707 Bad Cop Team Colleague

I'm not sure why you thought you could fail to close a string with a double quote, then start a new string and the compiler would somehow know to concatenate them. As long as there's nothing but whitespace between two string literals you can get that effect, but the strings each have to be complete:

infotxtbox->Text = "Name: Peter Jaško "
                   "Rank: Main Tech Manager, Vice-Leader, "
                   "Donated: ?, "
                   "Exp: ?";
Narue 5,707 Bad Cop Team Colleague

I can't find any mention of what happens to that object after the exception is finished

Finished by being caught and handled, or finished by being unhandled? In the former case, the destructor is properly called and the object ends after the final exception handler completes. In the latter case, abort is called, which is a hard terminate on the program.

Narue 5,707 Bad Cop Team Colleague

>DNA Mate = *(testDNA.CrossoverMutate(testDNA2));
The copy constructor will be called here to initialize Mate with the dereferenced pointer. If you don't want that happening, make Mate a pointer as well:

DNA *Mate = testDNA.CrossoverMutate(testDNA2);
Narue 5,707 Bad Cop Team Colleague

The void* data = tail->data; isn't working.

What do you mean by "isn't working"? The code you posted clearly isn't your actual code, so I can't say for sure what the problem is.

Narue 5,707 Bad Cop Team Colleague

Existential question: If room 5 doesn't exist, are the lights on? ;)

WaltP commented: Good point... +15
Narue 5,707 Bad Cop Team Colleague

if so then why is the return type named int instead of char?

For the same reason the parameter type is int instead of char, and why getchar returns int: to support EOF. If EOF were representable by char, how would you know the difference between EOF and a legitimate character with the same value?

Narue 5,707 Bad Cop Team Colleague

count is reinitialized to 0 with every iteration of the loop, so any changes you make to it will be lost on the next iteration.

Narue 5,707 Bad Cop Team Colleague

Try to open it for reading. If it opens, it exists.

Narue 5,707 Bad Cop Team Colleague

Yes, it's possible. The destination array needs to be large enough to hold the replacement, and the process is rather manual. You'll shift everything to the right of the matching character to make a hole, then overwrite what was in the hole with the new data:

# Find 'e'
joey
  ^

# Shift everything after 'e' to make room for 3 characters
joe  y
  ^  ^

# Fill in the hole with the source string
jo!!!y
  ^  ^

Of course, if array1 is shorter than the matching string, you'll need to do the opposite and fill in the hole that's already there:

# Find "oe"
joey
 ^

# Shift everything after "oe" to fill in excess hole
joy
  ^

# Fill in the remaining hole with '!'
j!y
  ^

Don't forget to properly move your null character as well.

Joey_Brown commented: great help!! +1
Narue 5,707 Bad Cop Team Colleague

ref class does not have a user-defined copy constructor

I bet you're using stack semantics with a copy constructor expecting managed references:

using namespace System;

ref class example {
public:
    example()
    {
        Console::WriteLine("Default constructor");
    }

    example(const example^ ref)
    {
        Console::WriteLine("Reference copy contructor");
    }
};

int main(array<String ^> ^args)
{
    example a;
    example b = a; // Uh-oh, no copy constructor for stack semantics
}

This can be fixed by converting the object to a reference handle, which will call the correct copy constructor:

example b = %a;

Or you can support both managed references and stack semantics in the copy constructor:

using namespace System;

ref class example {
public:
    example()
    {
        Console::WriteLine("Default constructor");
    }

    example(const example% obj)
    {
        Console::WriteLine("Stack copy constructor");
    }

    example(const example^ ref)
    {
        Console::WriteLine("Reference copy contructor");
    }
};

int main(array<String ^> ^args)
{
    example a;
    example b = a; // Now it works
    example d = gcnew example(); // This works too
}
MasterGberry commented: Perfect +0
Narue 5,707 Bad Cop Team Colleague

does it take a lot of planning to get an idea of the classes etc needed for a large application?

Yes, but my idea of a large application is probably very different from yours. For example, your blackjack game example would be small to me.

What kind of time frame?

It depends on the scale of the project, the size of the development team, and client participation.

I think I have it in my head, that because small programs are so easy to write, and I can "make it up" as I go along, I therefore think large applications must be the same.

As the scale of a project increases, the rules change. So no, large programs are not the same as small programs. Fresh college graduates who think they're invincible geniuses are often chagrined when they face reality. ;)

Narue 5,707 Bad Cop Team Colleague

What is the best way to design a program?

Opinions will vary, and methodologies can be mutually exclusive (ie top-down vs bottom-up design). Design is actually a pretty deep subject.

Are there any specific steps i should take when designing a program?

In small programs, I'll just wing it and refactor as I go. For larger applications I'll usually start by coming up with user stories to help with visualizing the entire system. From there it's easier to dig down and add details with a big picture view.

Narue 5,707 Bad Cop Team Colleague

Catching up is not as difficult as starting.

How many people have you helped unlearn bad habits from Turbo C? I've helped hundreds, and my experience is that it's harder than learning modern C from the get go.

i have a compiler but it is not compatible to my OS (windows7).

Visual C++ 2010 Express
Code::Blocks
Pelles C
LCC-Win32

Narue 5,707 Bad Cop Team Colleague

null isn't a keyword in C. If you're checking for a null pointer, use 0 or the NULL macro.

Narue 5,707 Bad Cop Team Colleague

addinf and address are both pointers to structures, so you'd need to dereference the pointer before accessing members:

(*(*stud.addinf).address).housenumb = 123;

Alternatively, the arrow operator does this for you in a much more convenient manner:

stud.addinf->address->housenumb = 123;

Note that those pointers must point to something first. Pointers aren't magic.

vedro-compota commented: ++++ +1
Narue 5,707 Bad Cop Team Colleague

Correction, Ctrl+Z instead of Ctrl+C for Windows. Thanks to jonsca for catching the brain fart. ;)

Narue 5,707 Bad Cop Team Colleague

While turbo is outdated, its simplicity gives confidence to beginners, to start thinking like a programmer.

I fail to see how using a limited and ancient compiler (which tends to cause no end of unnecessary problems and questions) is justified by a minor confidence boost from a simple IDE. Further, there are modern IDEs that are simple, so you're doing nothing but encouraging people to be so stuck in the past as to make life vastly harder when they try to catch up.

Narue 5,707 Bad Cop Team Colleague

why is it allowed to store chars in ints.

char is an integer type, just with a smaller range than int . It makes sense that since int can hold every value char can, a widening conversion from char to int should be possible.

also if i put getchar in a while loop and make the condition t = eof, how does it know its the end of me typin something.

You signal end-of-file from the command line (Ctrl+C on Windows, Ctrl+D on Unix//Linux), getchar will recognize it, and return the EOF macro. Note that EOF is an integer, which is why you should use an int to store results from getchar.

Narue 5,707 Bad Cop Team Colleague

You can't declare static variables in a scope?

Do you have a book on C++? I get the distinct impression that you're guessing and going on intuition for the most part when writing this program.

Narue 5,707 Bad Cop Team Colleague

I am defining them later on

Apparently you're not doing it correctly, because the linker doesn't see them.

Narue 5,707 Bad Cop Team Colleague

Static data members still need to be defined.

Narue 5,707 Bad Cop Team Colleague

This is a different matter entirely. The question you linked to was specifically about not printing a line break after hitting the Enter/Return key. Your requirement is merely not to print a newline character, which you're already doing.

Narue 5,707 Bad Cop Team Colleague

Learning C from the command line -- holy shit! Insane confidence killer, for a beginner. imo.

It's still good experience. Even if you only work from the command line for a week, it'll give you a better understanding and appreciation of what the IDE does.

Narue 5,707 Bad Cop Team Colleague

I ws just wondering what kind of knowledge one would need to learn to program.

You don't need any knowledge, but computer power user skills will go a long long way. If, for example, all you know how to do is send email and surf the web, you'll have a time getting a compiler and debugger stood up for programming.

As for feeling stupid, get used to it. Any programmer who strives to improve will be in a constant state of confusion.

Narue 5,707 Bad Cop Team Colleague

The main function is still at the top lexical level. Don't nest it in a namespace.

Narue 5,707 Bad Cop Team Colleague

Under C/C++ -> Code Generation -> Enable Minimal Rebuild. Or you could search for it and actually learn how to do this stuff on your own.

Narue 5,707 Bad Cop Team Colleague

So turn /ZI off. It's the option immediately above /clr. You can set it to /Zi, that's compatible.

Narue 5,707 Bad Cop Team Colleague

Project -> Properties -> Configuration Properties -> C/C++ -> General -> Common Language Run Time Support. Set it to /clr.

Narue 5,707 Bad Cop Team Colleague

Wait, are you using the command line to compile or are you using Visual Studio?

Narue 5,707 Bad Cop Team Colleague

Are you compiling with the /clr switch?