deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Now reverseString() doesn't do any reversing. All it does is make a copy of strings in the array and print them as-is...

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

If I wanna show the items in queue. what reference it should send as argument.

It shouldn't send any reference, barring an ostream reference if you want to write to something other than stdout. Such an operation would be a member function that works with the internal state but doesn't change it. Using my class as an example:

void Queue::DisplayAll() const
{
    for (ListNode* p = head; p; p = p->next)
    {
        cout << p->value << ' ';
    }
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

You need to include the algorithm header for std::reverse(). You're also trying to pass an array of strings to reverseString() when it only accepts a single string object.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

The queue class should maintain an internal state that doesn't need to be shared with the outside world. If you do that then every object will represent a completely different queue and you can create as many as you want without them overlapping:

struct ListNode
{
    ListNode(int value);
    
    int value;
    ListNode* next;
};

ListNode::ListNode(int value): value(value), next(nullptr) {}

class Queue
{
public:
    Queue();
    ~Queue();
    bool Empty() const;
    int Next() const;
    void Enqueue(int value);
    void Dequeue();
private:
    // Disable copying to keep the example simple
    Queue(Queue const& obj);
    
    ListNode* head;
    ListNode* tail;
};

Queue::Queue(): head(nullptr), tail(nullptr) {}

Queue::~Queue()
{
    while (head != nullptr)
    {
        Dequeue();
    }
}

bool Queue::Empty() const
{
    return head == nullptr;
}

int Queue::Next() const
{
    return head->value;
}

void Queue::Enqueue(int value)
{
    if (head == nullptr)
    {
        head = tail = new ListNode(value);
    }
    else
    {
        tail->next = new ListNode(value);
        tail = tail->next;
    }
}

void Queue::Dequeue()
{
    ListNode* temp = head->next;
    delete head;
    head = temp;
}

#include <iostream>

using namespace std;

void FillQueue(Queue& q, int start, int finish)
{
    for (int i = start; i < finish; i++)
    {
        q.Enqueue(i);
    }
}

void DumpQueue(Queue& q)
{
    while (!q.Empty())
    {
        cout << q.Next() << ' ';
        q.Dequeue();
    }
    
    cout << endl;
}

int main()
{
    Queue q1, q2;
    
    FillQueue(q1, 0, 10);
    FillQueue(q2, 10, 15);

    DumpQueue(q1);
    DumpQueue(q2);
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

but this is also showing error

The code has syntax errors. C is case sensitive, but you use both pData and pdata to mean the same thing. Try this instead:

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

int main ()
{
    int i,n,big;
    int * pdata;
    printf ("Amount of numbers to be entered: ");
    scanf ("%d",&i);
    pdata = (int*) calloc (i,sizeof(int));
    if (pdata==NULL) exit (1);

    for (n=0; n<i; n++)
    {
        printf ("Enter number #%d: ",n);
        scanf ("%d",&pdata[n]);
    }
    big=pdata[0];
    for(n=0; n<i; n++)
    {
        if(pdata[n]>big)
        {
            big=pdata[n];
        }
        printf("%d",big);

    }
    free(pdata);
    return 0;
}

But your algorithm is excessively complicated. There's no need to store the numbers since you only need to retain the biggest one found so far:

#include <stdio.h>

int main(void)
{
    int num;
    
    printf("Enter a series of numbers (EOF to stop): ");
    
    // Get the first number separately to simplify the logic
    if (scanf("%d", &num) == 1)
    {
        int largest = num;
        
        // Now get the rest of the numbers and find the largest
        while (scanf("%d", &num) == 1)
        {
            if (num > largest)
            {
                largest = num;
            }
        }
        
        printf("The largest was %d\n", largest);
    }
    else
    {
        printf("No numbers were entered.\n");
    }
    
    return 0;
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

malloc is a void function so you have to bring it into a any pointer type like (int*),(float*),or(double*)

That's a confusing statement, and it's also incorrect. When people say "void function" they typically mean a function that returns void, not a generic pointer to void. A more accurate, but still incorrect statement would be:

"malloc() returns a pointer to void, so you have to cast it into the destination pointer type."

But C allows an implicit conversion between void* and any non-function pointer type without a cast. In fact, adding the cast is dangerous because it can hide the warnings you would get by forgetting to include stdlib.h.

A good pattern for malloc() that I see a lot is this:

p = malloc(n * sizeof *p);

No cast is needed, and sizeof *p gets the size of the pointed-to type without having to name it explicitly. That way if you decide to change the type, you don't need to change the call to malloc(). So your code, with a few alterations, would look like this:

double *matrix;
int n;

printf("input dimension: ");
fflush(stdout); // Force the prompt to show before blocking

if (scanf("%d",&n) != 1) // Always check input for failure
{
    // Handle failure
}

matrix = malloc(n * sizeof *matrix);

if (!matrix) // Always check malloc() for failure too :)
{
    // Handle failure
}

One caveat to omitting the cast is that if you're writing code that needs to compile as both …

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Hmm thank you, and yeah like if i have a problem, what steps must i under go to solve it. etc... So its really not important that i know these things?

It's critical that you know those things. Problem solving is the core of programming after all, but I'm not aware of any resources that teach it in a methodical way. It's mostly just trial and error. However, if you're interested in boosting your understanding of computer science, I'd say start seriously learning data structures and algorithms. You'll find that a strong foundation in those two goes a loooooong way, mostly because all of the key concepts for programming can be gleaned out of studying data structures and algorithms. :)

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

The overloaded<< operator only allows non-const references, which excludes temporaries like the ones returned by transpose() or calculated with the overloaded operator*. You should change it to expect a reference to const instead as you don't make any changes to the object's state:

ostream &operator<< (ostream &out, Matrix const &myMatrix)
{
	for(int i=0; i < myMatrix.num_rows(); i++){
		for (int j=0; j< myMatrix.num_cols(); j++){
			out.width(3);
			out << myMatrix.get_element(i,j) << "  ";
		}
		out << endl;
	}
	out << endl;
	return (out);
}

That also requires the called methods of num_rows(), num_cols(), and get_elements() to be declared as const methods, but that's how they should be defined anyway to maintain const correctness:

int Matrix::num_rows() const
{
	return numRows;
}

int Matrix::num_cols() const
{
	return numColumns;
}

ElementType Matrix::get_element(int row, int col) const
{
	return myArray[row][col];
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

waiting for your kind reply anxiuosly.

My reply remains the same, the problem is exactly as speculated: your queue methods are nothing but glorified functions. They don't work with any internal state, so it's totally irrelevant which object you call queue_display() on; it'll still only display the contents of the argument.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

what is the use of -> in c.

a->b is equivalent to (*a).b . It's syntactic sugar for accessing members of a structure through a pointer to an instance of the structure.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

why instead of this why cant we use array???

And if you don't know the size of the array at compile time?

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Can I say, the binary tree T that gave this inorder traversal is a binary search tree.

Technically yes, until you make any changes to the tree.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

scanf("%s",&x);

i think it's suitable....

x is a char, not an array. There's insufficient space to hold both the character typed and the '\0' character that scanf() adds automatically.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

when I tried to insert element is "weather" queue and display it shows the same element in all the queues declared.

Yes, that's what you appear to have told it to do:

// Insert message and return the resulting queue (I'm assuming)
head= weather->enqueue(head,(gcnew message("*144")));

// Display the provided queue, which refers to weather
news->queue_display(head);

// Display the provided queue, which refers to weather
weather->queue_display(head);

I'm assuming that queue::enqueue() returns a pointer to the front of the queue, and queue::queue_display() displays the contents of the argument instead of the contents of the object on which it's being called. I can confirm or reject those assumptions if you post the full definition of the queue class.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

if the inorder traversal of a binary tree is sorted, then is it necessarily a binary search tree?

While that exact tree would represent a binary search tree, I'd say that it's not a binary search tree unless the algorithms used to insert and update it maintain that order. Otherwise it's just a binary tree that happened to have a state matching a binary search tree.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

I already know syntacs of OOP in PHP, but I find it kind of hard to start working with it, I can't find some nice and SIMPLE examples of object oriented PHP.

In my experience you won't find good *and* simple examples. OOP is best suited to larger projects, and larger projects have a tendency to be anything but simple. ;)

My question is, should I start with that framework now, with limited knowledge of OOP or I should master OOP first?

I'd say start working with the framework and learn OOP as you go. You're not going to master OOP without using it in real applications anyway, and missteps are to be expected, so go at it and don't be afraid to mess up a design or two. Throwing away failed attempts comes with the territory.

I'm not sure I will understand it completely if I'm not comfortable with Object Oriented Programming first.

Perhaps not, but in figuring it out, you'll become more comfortable. Here's a shocking revelation: professional programmers learn things on the way and rarely are comfortable with all aspects of any new project unless they've holed themselves up in a comfortable niche.

zack654 commented: Thanks a lot mate ;) +1
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Wow, there are some unsympathetic people here. :icon_rolleyes: If it's legitimate harassment then that's an issue, but to the best of my knowledge there's no way to find out who is doing the voting without direct database queries, if that information is presently stored at all.

You'd need to contact Dani for such a task as she's the only one with database access in the current system.

happygeek commented: Agreed +0
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

But I would like to know, what are the other things that make the code 'unclean'.

  • Global variables where they're unnecessary.
  • Using malloc() when it isn't justified.
  • malloc.h isn't the correct header for malloc(), it should be stdlib.h.
  • No error checking of malloc() or input functions.

I also think mixing formatted and unformatted input is unclean because it forces you to do stuff like flushing the input stream, but that's a personal opinion. It's easier to use fgets() for all input and then parse it to get non-string types:

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

int* fgeti(int* var, FILE* strm)
{
    char buf[BUFSIZ];
    
    if (fgets(buf, sizeof buf, strm) &&
        sscanf(buf, "%d", var) == 1)
    {
        return var;
    }
    
    return NULL;
}

int main(void)
{
    char name[200];
    int id;
    
    if ((printf("Enter id: "), fgeti(&id, stdin)) &&
        (printf("Enter name: "), fgets(name, sizeof name, stdin)))
    {
        printf("\n[%s] is [%d] years old", name, id);
        printf("\nAscii of name = %d", *name);
    }

    return 0;
}

Also please tell me why the ascii printed reads 0.

The only reason I can think of is you typed the enter key and nothing for the name. gets() doesn't store a new line character in the string like fgets(), so you're looking at the null character terminator.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Yes, I did try using a fflush(stdin) between the 2 inputs, still doesn't work.

You're making the assumption that fflush(stdin) is clearing the input stream, which isn't a safe assumption. Technically it's undefined behavior to call fflush() on an input stream. As a quick test, replace the fflush(stdin) line with this one:

while (getchar() != '\n');

Also check to see if malloc() returned a null pointer. It would likely crash if that were the case, but you might otherwise get some odd behavior.

Do those two things and come back if they don't have any difference. There are a number of things that could go wrong with this program, but I don't want to overwhelm you with possibilities. :)

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Why do you need a 2D array if you already have a class holding the data?

personClass[] people = new personClass[N];

for (int i = 0; i < N; i++)
{
    people[i] = new personClass();

    people[i].Name = "John Doe";
    people[i].Address = "123 Nowhere Lane";
    people[i].Phone = "(555) 555-5555";
    people[i].PostCode = "12345";
    people[i].Height = "182cm";
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

The draft standard will tell you what's legit as far as C++ goes. The competition might have another definition of "standard" though.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

However,it seems that i cant use 'if else' to call them

Could you elaborate on this? The only real problem with how you're calling the functions is that they don't exist; you've only declared the function signatures, not actually defined the function bodies.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Can you do any part of it? Because Daniweb's rules state that you can't just post program requirements and expect someone to give you the code. You'll get more help by trying something and then asking specific questions if you have problems.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

The only problem I see is processing the # wildcard. Other than that it's a simple matter of grabbing a word from both the pattern and the source string, then either checking them for equality or not depending on if the pattern word is a * wildcard.

Processing a # wildcard is kind of tricky if you also want to check literals beyond it. So if "#.dsf" should match "eur.stock.dsf" but not "stock.nasdaq", the algorithm needs to consider how many pattern words are remaining and not match too much when processing a # wildcard.

So maybe something like this pseudocode:

WHILE more pwords AND more swords DO
    IF pword = "#" THEN
        -- Get the next non-# pattern word
        NEXT pword WHILE pword <> "#"

        IF NOT more pwords THEN
            -- # is the last word in the pattern, so it matches everything
            RETURN true
        ELSE
            remaining := COUNT pwords

            -- Match everything up to the first remaining pattern word
            WHILE remaining > 0 AND more swords DO
                DECREMENT remaining
            LOOP

            IF remaining = 0 THEN
                -- Insufficient words in the source to match remaining pattern words
                RETURN false
            ENDIF
        ENDIF
    ELSE
        IF pword <> "*" AND sword <> pword THEN
            -- The source word doesn't match a literal pattern word
            RETURN false
        ENDIF
    ENDIF
LOOP

RETURN NOT more pwords OR more swords
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

hy your past it's grand but i dont get that at all cause i never done that before so i dont know how to do it
the code that i put up was guessing how to do it

The takeaway lesson is that decryption is a mirror image of encryption, and your code should reflect that (pun intended):

#include <iostream>
#include <string.h>
#include <ctype.h>
using namespace std;

int main()
{
    system("Color 1A");

    char clear[200] = {0};
    char cipher[200] = {0};
    int x,i;

    cout << "what do you want to do with your password " << endl;
    cout << "1 Encrypt your password " << endl;
    cout << "2 Decrypt your password " << endl;
    cout<<" Enter a string:";
    cin.getline(clear,sizeof(clear));

    x = strlen(clear);
    // Encryption
    for(i=0; i<=x-1; i++)
    {
        if (isspace(clear[i]))
        {
            cipher[i] = clear[i];
        }
        else
        {
            cipher[i] = clear[i]+3;
        }
    }

    // Decryption
    for(i=0; i<=x-1; i++)
    {
        if (isspace(cipher[i]))
        {
            clear[i] = cipher[i];
        }
        else
        {
            clear[i] = cipher[i]-3;
        }
    }

    cout<<" Encrypted:" << cipher << endl;
    cout<<" Decrypted:" << clear << endl;

    return 0;
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

The C standards indicate that "char" may either be a "signed char" or "unsigned char".

Yes.

That said, if it's being used to hold a value between 0 and 255 it doesn't matter what it is - all char values can hold at least 256 different values; you just need to know what the chosen encoding mechanism is.

No. The char type is allowed a minimum size of 8 bits, which is very common. In that case the range of signed char is approximately -127 to +127, with a slight variance depending on the system's signed integer representation.

So while you're right that all char values can hold at least 256 different values, those different values can vary greatly between signed and unsigned. If you have a signed char as described above and try to assign anything greater than 127, the signed overflow will invoke undefined behavior.

I have read conflicting reports on the char/uchar front though, but every article I've read has been conflicting, so I guess there is really not much difference.

There's really no conflict. Vanilla char is either signed or unsigned as decided upon by the compiler. For that particular compiler it won't change, but if you want to write portable code, it's best not to assume that char is signed or unsigned and use signed char or unsigned char explicitly when the difference matters to your program.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

thanks for that

any one ells how to do it
plz help

Was my post not clear enough? Please point out what's not clear to you and I'll be happy to explain further.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster
cout << "please enter your first and last name" << endl;
cin  >> name;

That is your problem, and this is the fix:

cout << "please enter your first and last name" << endl;
getline(cin, name);

The reason it's the problem is operator>>() stops reading at whitespace. So if you type "Joe Schmoe", name will only get populated with "Joe", and " Schmoe" will be left in the stream for the next input request.

The next input request is cin >> photos, which is looking for a double value, so it will fail on "Schmoe" and put cin into an error state. Thus all of your requests for input from cin after that will fail to do anything and you'll be working with mostly uninitialized variables.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

so, info is a Information struct

Those two lines are only meaningful if info is a pointer to an Information object.

is there any different between the two shown above?

Nope, the arrow operator is for convenience when dereferencing a pointer member.

and what is "->" and "." called?

They're the the arrow and dot operators. :)

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

in the same directory as the .cpp file so I'm lost right now.

That's probably your problem. Typically relative file names will be looked for in the current working directory, not the source file directory. Sometimes those will be the same, but more often than not they won't be.

The current working directory is probably going to be the same directory as where the executable is. You might be able to see it with a test program like this:

#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    if (argc >= 1)
    {
        cout << "Current working directory: " << argv[0] << endl;
    }
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

but when i build i still get the error message

What's "the error message"? If you mean when you *run* the program you get the error opening file message, then I'd suggest using perror() to get more details:

if (infile.fail()) {
    perror("Error opening file!!! Now closing program!!!");
    exit(1);
}

Don't forget to include <cstdio> for perror()'s declaration.

Oh and I know exit(1); is an un-natural way of closing the program because it literally crashes it

Not really. exit(1) is identical to return 1 from main(). You're probably thinking of abort().

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

For a rotating cipher you would reverse the operation to decrypt. So add 3 for encryption and subtract 3 for decryption:

#include <iostream>
#include <string>

using namespace std;

string Encrypt(string const& s)
{
    string result;

    for (int i = 0; i < s.size(); i++)
    {
        result.push_back(s[i] + 3);
    }

    return result;
}

string Decrypt(string const& s)
{
    string result;

    for (int i = 0; i < s.size(); i++)
    {
        result.push_back(s[i] - 3);
    }

    return result;
}

int main()
{
    string cipher = Encrypt("testing 1...2...3...");

    cout << cipher << endl;
    cout << Decrypt(cipher) << endl;
}

The above example is broken, by the way. If the char type is signed and adding or subtracting 3 from s would overflow, the program invokes undefined behavior. But working around that is a lesson for another day. :) Best it keep things simple at first.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Endianness only matters when you make an assumption about how bytes are organized. Bitwise operators will work with the value and have consistent behavior regardless of the endianness of the system, and that's one way to ensure portable code when sending or receiving binary data:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <limits>
#include <type_traits>
#include <vector>

using namespace std;

template <typename T>
vector<unsigned char> GetBytesNonPortable(T value, typename enable_if<is_integral<T>::value>::type * = nullptr)
{
    // Extract bytes as stored in memory (different endianness will give different results)
    unsigned char* pun = (unsigned char*)&value;

    return vector<unsigned char>(pun, pun + sizeof(T));

}

template <typename T>
vector<unsigned char> GetBytesPortable(T value, typename enable_if<is_integral<T>::value>::type * = nullptr)
{
    unsigned const bits = numeric_limits<unsigned char>::digits;
    unsigned const max = numeric_limits<unsigned char>::max();

    vector<unsigned char> result;

    // Extract bytes regardless of endianness
    for (size_t i = 0; i < sizeof(T); i++)
    {
        result.push_back((value >> (bits * i)) & max);
    }

    return result;
}

int main()
{
    int value = 12345678;
    vector<unsigned char> v1 = GetBytesNonPortable(value);
    vector<unsigned char> v2 = GetBytesPortable(value);

    copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " ")), cout << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, " ")), cout << endl;
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Some folks really believe in DataSets, DataAdapters and DataTables.

The implication being that you think they're not a good solution? If so, please explain why. I always enjoy hearing different perspectives. :)

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

AFAIK, BBCode is accepted in either upper or lower case.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

function starts with a void....

Then you would use an empty return statement:

void foo()
{
    ...

    if (some error)
    {
        return;
    }

    ...
}
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Oh, I didn't see that a seg fault was one of the potential errors. My bad.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

By auto parse do you mean turn a URL into a clickable link?

Starting off in the new system there will be only one editor, and we're moving from BBCode to Markdown for formatting purposes. I doubt that's going to change this close to release, so I feel comfortable stating it publicly. ;)

As far as things are in dev right now, there's no auto parsing of URLs in the final post. You would need to use a proper Markdown format to make the link clickable:

This will be parsed: http://www.daniweb.com
This will not be parsed: [noparse]http://www.daniweb.com [/noparse]

In the current system, you can just wrap your URLS in noparse tags: [noparse]http://www.daniweb.com [/noparse]. The only down side to that is there's no convenient button for noparse tags, they must be typed manually. But it's much better than the rigmarole you've been going through with switching vBulletin editors.

diafol commented: noparse - no brainer! +0
deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Return from the function with a return statement and the program will continue to run from that point on. But if the program depends on results from the function that errored, you'll have problems later on.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Whats wrong with this line.Returning an error C2065: 'getline' : undeclared identifier

getline(cin,test.name);

Ah, the code shouldn't compile, maybe my compiler's settings aren't strict enough. :D This error means that there's no #include <string> directive. That's where the version of getline() that works with std::string is declared.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

Does that mean the values for B, C and D are randomized too?

Well...yes. When you call rand() it gives you the next pseudorandom number in the sequence. The sequence can be reset by calling srand().

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

It's the preprocessor's pastie operator. It takes two tokens and concatenates them into a single token. For example:

#include <stdio.h>

#define PASTIE(prefix, var) prefix ## var

int main(void)
{
    char const* strFoo = "foo!";
    
    puts(PASTIE(str, Foo));
    
    return 0;
}

Neither str nor Foo are meaningful by themselves, but when combined they match the variable name strFoo, so this code both compiles and prints "foo!" to stdout.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

customer id genrated by rand will then be updated to real customer id once customer has logged in.

I'm not sure I understand the logic. You're generating a temporary id for some reason?

what do you suggest then? is there such thing as setting a certain session id?

I'd need a better idea of what you're trying to accomplish to make a suggestion.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

You're not doing anything wrong. Windows Forms is notorious for having a noticeably slow redraw out of the box. There are a number of ways to improve matters, but the list is kind of long, so I'll just suggest searching google.

One thing to keep in mind is that C# has to go through the .NET framework while VB6 would hit the Win32 API directly. There's a whole extra layer or two difference, though that's not an excuse for the unresponsiveness of WinForms. ;)

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

can I be assured that every guest who visits the site has a unique session id?

No, though the likelihood of a collision is rather low.

and for example I use a rand() to generate and store a $_SESSION

can I be assured that every set of rand() is also unique?

Certainly not, and the likelihood of repeated random numbers is very good. If you want a unique customer id then I'd recommend looking into options other than just a pseudorandom number.

Is the customer id only used for that session, or are you storing it in a database for later retrieval?

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

That depends on the algorithm rand() uses. It's probably some form of linear congruential random number generator, but there's so many of those it's impossible to tell what sequence will result without seeing the code or doing a lot of analysis on produced sequences.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

What kind of strings? If they're std::string objects then they're not pointers and cannot be compared to nullptr.

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

What are A and B?

deceptikon 1,790 Code Sniper Team Colleague Featured Poster

If the seed is always the same, the pseudorandom sequence will always be the same. Change the seed to something other than 8, and A will probably be different.