Luther von Wulf 7 Light Poster

Is this dynamic array procedure something that's not suitable for use with objects?

Dynamic arrays work with objects, the problem is the value of the static variable Fuzzy::n. Destructors are only called if the memory is freed, so if you create an array of 10 in the first iteration of the loop without freeing the array, then 2 in the second, Fuzzy::n never decreases to 0. The initialization will try to populate an array of 12 when there are really only 2 elements. The fix is of course to free the array.

int main () {
    int i;
    Fuzzy *ent;
    while(1){
        cout << "How many objects? ";
        cin >> i;
        ent = new (nothrow) Fuzzy[i];
        if( ent == 0 )
            cout << endl << "No memory!";
        for( int n = 0; n < Fuzzy::n; n++){
            for( int i = 0; i < 48; i++ )
                ent[n].position[i] = 24;
            ent[n].score = 567;
        }
        cout << ent[0].n << endl;
        delete[] ent; // this line was added
    }
}
Luther von Wulf 7 Light Poster

When I was in school, we were expected to do our own homework. Has this changed?

Luther von Wulf 7 Light Poster

celltype is wrong because the function is hashing the student ID. The list is irrelevant to that task. x should have a type of student instead.

Concerning sum, first and foremost it must be initialized. The += operator uses the current value within sum and adds to it, if sum is uninitialized, the result is unpredictable.

Next, modulo is used to get the least significant digit and division removes it. Also, the easiest way to stop a loop that is removing digits is to stop when the number reaches 0. This way the number of digits in the ID no longer matter. If another digit is added, the code does not need to change.

int Hash(student x)
{
    unsigned long ID = x.ID;
    int sum = 0;
    while (ID) {
        sum += ID % 10;
        ID /= 10;
    }
    return (sum % maxGrp);
}
Luther von Wulf 7 Light Poster

just tried using fgets() (see below) but I run into message "warning: passing argument 1 of ‘fgets’ makes pointer from integer without a cast"

fgets() requires an array of char for the first argument.

#include <stdio.h>

int main() {
    char input[BUFSIZ];
    printf("\nTo calculate a^b, enter value a now.\n");
    int a = *fgets(input, BUFSIZ, stdin) - '0';
    printf("\nEnter b now.\n");
    int b = *fgets(input, BUFSIZ, stdin) - '0';
    printf("a = %d, b = %d\n\n", a, b);
    return 0;
}

unfortunately, works exactly the same as getchar().

Yes, getchar() is implemented in terms of fgetc(). The best way using getchar() is a loop until the '\n' character is found. The '\n' character in an interactive stream means that the user typed the return key.

#include <stdio.h>

void iflush(FILE* istrm) {
    int c;
    while ((c = getc(istrm)) != '\n' && c != EOF)
        ;
}

int main() {
    printf("\nTo calculate a^b, enter value a now.\n");
    int a = getchar() - '0';
    iflush(stdin);
    printf("\nEnter b now.\n");
    int b = getchar() - '0';
    printf("a = %d, b = %d\n\n", a, b);
    return 0;
}
Luther von Wulf 7 Light Poster

I have been advised by many people that it is better to use integer return type for main function instead of void !

That is good advice if you want the code to be maximally portable without any changes.

I actually dont understand what return 0 means

It means the same thing it means when you call a function with a return value.

#include <stdio.h>

int function() {
    return 0;
}

void main() {
    if (function())
        puts("0 was returned");
}

The only difference is the operating system calls main(), and the operating system uses the return value when main() returns.

Luther von Wulf 7 Light Poster

There are two logical parts to an array. The capacity is set by the declaration. For the declaration int a[10]; , 10 is the capacity. It is the maximum number of elements that can be stored in the array. The size is the number of used elements in the array. Using the previous declaration, the size is 0 and the capacity is 10. After filling one element with a[0] = 10; , the size is 1 and the capacity is 10. The size is not known by C, you must maintain it with a separate variable.

The capacity will always remains the same, but elements can be removed by overwriting and decreasing the size. Overwriting is done by taking a block of elements from N to the current size and moving it left by 1. Then the size is decremented. C does not support that kind of block movement, but it can be done element by element with a loop.

#include <assert.h>
#include <stdio.h>

void remove_at(int* a, int* sz, int at) {
    assert(at >= 0 && at < sz);
    // move the [at+1,sz) block left by 1
    while (at++ < *sz)
        a[at-1] = a[at];
    --*sz; // the array has shrunk by 1
}

void list(char const* prefix, int* a, int sz, FILE* ostrm) {
    int x;
    fputs(prefix, ostrm);
    for (x = 0; x < sz; ++x)
        printf("%d%c", a[x], (x < sz-1 ? ',' : '\n'));
}

void main() {
    int a[10] = {0};
    int sz = 0;
    while …
Luther von Wulf 7 Light Poster

if i have two strings say:

string str1,str2;

then how can i compare them by using strcmp function?

The strcmp() works with C strings. The string class has comparison built in using both operators and the compare() method. The compare() method is the closest match to strcmp(), but if you still want to use strcmp(), call the c_str() method to get a C string from a string object.

int cmp = strcmp(str1.c_str(), str2.c_str());
Luther von Wulf 7 Light Poster

floats can be used as a counter, but you must be very careful in comparing them because they are approximations of values and have inaccuracy where two values that seem the same are not exactly the same. A fuzzy comparison is usually used for floating point. Here is your code with the fuzzy comparisons added.

#include<iostream>
#include<iomanip>
#include<limits>
#include<math.h>
using namespace std;

inline bool less_than(float lhs, float rhs) {
    float sig = fabs(lhs) < fabs(rhs) ? fabs(rhs) : fabs(lhs);
    return rhs-lhs > sig * numeric_limits<float>::epsilon();
}

inline bool equal_to(float lhs, float rhs) {
    float sig = fabs(lhs) < fabs(rhs) ? fabs(rhs) : fabs(lhs);
    return fabs(lhs-rhs) <= sig * numeric_limits<float>::epsilon();
}

inline bool less_or_equal(float lhs, float rhs) {
    return less_than(lhs, rhs) || equal_to(lhs, rhs);
}

int main() {
    float start_temp,stop_temp;
    float step,F,C;
    cout<<"start temperature:";
    cin>>start_temp;
    cout<<"stop temperature:";
    cin>>stop_temp;
    cout<<"step temperature:";
    cin>>step;
    float i=0;
    cout<<setw(10)<<"celsius"<<setw(15)<<"fahrenheit"<<endl;
    cout<<setw(25)<<"celsius"<<setw(15)<<"fahrenheit"<<endl;
    for(i=start_temp; less_or_equal(i, stop_temp); i=i+step) {
        C=(5.0/9.0)*(i-32);
        F=32+(9.0/5.0)*i;
        cout<<setprecision(2);
        cout.setf(ios::fixed);
        cout<<setw(10)<<C<<setw(10)<<i<<setw(10)<<F<<endl;
    }
}
Luther von Wulf 7 Light Poster

The solution is to get a newer compiler and use graphics libraries that are better suited to Windows 7. Turbo C++ can probably be made to work through extreme compatibility, but it was written for Windows 3.1 and is so far out of date that new code should not be written with it.

jonsca commented: Yes +4
Luther von Wulf 7 Light Poster

This function reformats a numeric sequence to include grouping in the usual human readable format. "123456789" becomes "123,456,789", for example. The formatting is localized to the current running machine. In a German locale the previous example becomes "123.456.789". In a Hindi locale it becomes "12,34,56,789". Printing numbers for human consumption is a common request. C does not offer direct support for it, nor are there many examples that are complete for use outside of the US that I could find.

Adak commented: Looks very robust - well done. +3
Luther von Wulf 7 Light Poster

Well..it's not completely true...'cause with a "special" char I could consider only the runs longer than 3.
So that "NTBBOP" remains as it is, without losing anything.

Then you need some kind of escape for the "special" character unless it is so special that it will never be in the unencoded string. The fact still remains that RLE is not suitable for input that has few long runs. If the input is degenerate enough that the encoding of short runs is not alleviated by the encoding of long runs, RLE is a poor choice of compression.

Luther von Wulf 7 Light Poster

There is no function to do this kind of numeric formatting, but one can be written. The hardest part is the group separation with commas.

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <locale.h>
#include <ctype.h>

typedef enum { FALSE, TRUE } BOOL;

BOOL format_numeric(char const* num, char* buf, int buf_sz) {
    int num_x = strlen(num)-1, buf_x = 0;
    int group_sz = 0; // current group size
    struct lconv* lc;
    char* group; // current group maximum size
    setlocale(LC_NUMERIC, "");
    lc = localeconv();
    group = lc->grouping;
    buf[buf_x] = '\0'; // make strcat() work
    while (num_x >= 0) {
        if (!isdigit(num[num_x]) || buf_x >= buf_sz-1)
            return FALSE;
        if (*group != CHAR_MAX && group_sz++ == *group) {
            strcat(buf, lc->thousands_sep);
            buf_x += strlen(lc->thousands_sep);
            if (*group != lc->grouping && *(group+1) != 0)
                ++group;
            group_sz = 0;
        }
        else {
            buf[buf_x++] = num[num_x--];
            buf[buf_x] = '\0'; // make strcat() work
        }
    }
    strrev(buf);
    return TRUE;
}

void main() {
    char buf[20+1];
    if (format_numeric("1000000000", buf, sizeof buf))
        printf("|%s|\n", buf);
    else
        fprintf(stderr, "conversion error\n");
}

Currency is even harder, but it seems as if you are only appending ".00" to the user input instead of interpreting an assumed decimal: "1523" with an assumed decimal becomes "15.23".

Luther von Wulf 7 Light Poster

Thanks for your reply, and for the good idea.
However what happens if in the original file I've a run long 2?
For example "NTBBOP" should become "NTBB2OP", increasing the result of 1 char

This would be a problem with the special character approach also, "NTBBOP" becomes "NTB*2OP". RLE is very sensitive to the input. One degenerate case for RLE is many runs where the encoding is longer than the run. If such degenerate cases are expected, RLE is not a suitable compression method.

Luther von Wulf 7 Light Poster

The parentheses around void seem to be the problem. Does this produce the same error?

struct 	
{	
    void (*function)();	
    const char* functionName;
} 
lookUpTable[] = { {&TSL1_ReadMemory32, "ReadMemory32"}, {NULL, NULL} };
Luther von Wulf 7 Light Poster

Because of how RLE works, a run of two will not naturally be in the encoded string. You can use a run of two of any character as a special sequence that signifies the start of an encoded run for that character. In your example, "ABRTTTTOPSSSSSNU" becomes "ABRTT4OPSS5NU" with the following logic.

; encode RLE
while not eof(istr)
    current = get_next_char(istr)
    length = 1
    while peek() = current
        get_next_char(istr) ; eat the run
        length = length + 1
    if length > 1
        write_n(ostr, current, 2)
        write(ostr, length)
    else
        write(ostr, current)
; decode RLE
while not eof(istr)
    current = get_next_char(istr)
    if peek() = current
        get_next_char(istr) ; eat the duplicate
        length = get_next_int(istr)
        write_n(ostr, current, length)
    else
        write(ostr, current)

This way there is no worry about special characters being in the unencoded data because there are no special characters, just a special sequence of any character that would otherwise not exist.

Luther von Wulf 7 Light Poster
connections[k++]=&(slot(ii,jj));

This line is suspicious. If connections is a vector, then either it should be resized to have enough space beforehand, or push_back should be called to add a new element each time. Indexing does not resize the vector, that might be why the size is different from how many elements you have tried to add.

connections.push_back(&(slot(ii,jj));
++k;
Luther von Wulf 7 Light Poster

I don't understand. The number of spaces should be different because the "hello" and "3.141567" are different lengths. The spaces are padding within the specified field width of 10, they fill in what the strings do not.

Luther von Wulf 7 Light Poster

This is what is called a dependent type because the type of the vector size_type is dependent on is also dependent on a template argument. It is fixed with the typename keyword.

template <class Type>
class Some
{
	private:
		vector<Type> elements;
		typename vector<Type>::size_type index;
	public:
		Some() { }
};

When Type is replaced with int, size_type is no longer a dependent type because there is no dependency on a template argument.

Luther von Wulf 7 Light Poster

With std::string you can just add them:

It might be best practice to use the string class, but this does not answer the question of why there is a runtime error in the posted code.

Luther von Wulf 7 Light Poster

I think dynamic_cast is better than reinterpret_cast

Doesn't dynamic_cast only work with polymorphic types?

Luther von Wulf 7 Light Poster

I read about an older bug in the GNU compiler where C++ strings did not work with setw(), but string constants did. Does this work for you?

#include <iostream>
#include <iomanip>

using namespace std;

int main() {
    char const* a = "hello";
    cout<<"|"<< setw(10) << a <<"|"<<endl;
}
Luther von Wulf 7 Light Poster

For any other object that is not the "this" object, protected members are inaccessible, just like if they were private, as far as Foo is concerned or any other derived class for that matter.

What you say is not completely correct, for the following code compiles and runs.

#include <iostream>

using namespace std;

class A { protected: int x; };
class B: public A {
public:
    B(int x) { this->x = x; }
    int get_this() const { return x; }
    int get_that(B const& obj) const { return obj.x; }
    int get_local() const {
        B obj(30);
        return obj.x;
    }
    friend int get_friend(B const& obj) { return obj.x; }
};

int main() {
    B obj1(10), obj2(20), obj3(40);
    cout<< obj1.get_this() <<endl
        << obj1.get_that(obj2) <<endl
        << obj1.get_local() <<endl
        << get_friend(obj3) <<endl;
}

Within the definition of the derived class or friends of the derived class, non-public members of other objects of the same class type are accessible. Non-public members of objects of other class types, including the base class, are still not accessible.

Luther von Wulf 7 Light Poster

strcat_s() takes 3 arguments, not 2. And just like strcat(), a precondition is that the string is already zero terminated. Meet the precondition and supply the required arguments and it will work as expected.

person1.m_name[0] = '\0';
strcat_s(person1.m_name, 40, "Dan");

For initialization, strcpy() or strcpy_s() are better choises.

Luther von Wulf 7 Light Poster

This is interesting. I do not see the same problem with your code on my compiler. What compiler are you using? If you break down the operations, does it still not work?

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

using namespace std;

int main() {
    float a=3.141567;
    string b="hello";
    cout<<"|";
    cout.width(10); // strip out the setw()
    cout<<b<<"|"<<endl;
    cout<<"|"<<setw(10)<<a<<"|"<<endl;
}
Luther von Wulf 7 Light Poster

My guess is that GetSymbol() returns a void*, and void* is not compatible with function pointers. Try a cast, you might get lucky.

helloSteve myFunc = reinterpret_cast<helloSteve>(myDLL->GetSymbol(wxT("helloSteve")));
Luther von Wulf 7 Light Poster

the (int) cast is from C, and is not recommended in C++ for good reasons. Use the "functional" casting:

//check the video info header
Width  = int(&pVideoInfoHeader->bmiHeader.biWidth);
Height = int(&pVideoInfoHeader->bmiHeader.biHeight);

//break point here

The functional cast is still the same thing as the C cast, and it has all of the same problems. The only difference is more of a constructor look in the syntax. The real C++ casts that are recommended for better code are named and specialized. In the case of explicitly casting from long to int, the static_cast operator is the recommended C++ tool.

Width = static_cast<int>(pVideoInfoHeader->bmiHeader.biWidth);
Height = static_cast<int>(pVideoInfoHeader->bmiHeader.biHeight);
Luther von Wulf 7 Light Poster

In what way is it not working? The same code works ok for me.

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

using namespace std;

int main() {
    string a = "hello";
    cout<<"|"<< setw(10) << a <<"|"<<endl;
}
Luther von Wulf 7 Light Poster

What are good name conventions for classes. How for example should the name be different between a base class and a derived class or an abstract class and a concrete class?

Luther von Wulf 7 Light Poster

Although you *solved the problem fast, it could be better.

I would like to know how to make it better, but that is a question for another thread.

How far of C++ do you know? Any knowledge about meta-programming?

The C subset, classes and basic OO. I know about template for simple genericity and some STL, but no meta-programming.

Luther von Wulf 7 Light Poster

cell should not be dereferenced in the first call to malloc(), and the cast is missing a level of indirection.

cell = (s_cell**)malloc(sizeof(s_cell) * MAP_X);
Luther von Wulf 7 Light Poster

Cut off the upper end of the range to account for the addition.

rand() % (20-8) + 8
Luther von Wulf 7 Light Poster

This is my solution to your signature problem. Does it tell you what I know about C++?

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
using namespace std;

string toMathEquation(string const& expr);
bool is_operator(string const& term, string& val);
bool is_degree(string const& term, string& val);
bool is_literal(string const& term, string& val);
bool is_match(pair<string, string> items[], size_t sz, string const& term, string& val);
string to_string(size_t val);

int main() {
    cout<< toMathEquation("x squared plus nine x minus seven") <<endl;
    cout<< toMathEquation("two plus six x cubed minus x squared") <<endl;
    cout<< toMathEquation("negative x cubed divided two x squared") <<endl;
    cout<< toMathEquation("twenty-five times negative six x quartic") <<endl;
}

string toMathEquation(string const& expr) {
    stringstream reader(expr);
    string term, equation, val;
    while (reader>>term) {
        if (is_operator(term, val) || is_degree(term, val) || is_literal(term, val))
            equation += val;
        else
            equation += term;
    }
    return equation;
}

bool is_operator(string const& term, string& val) {
    pair<string, string> ops[] = {
        make_pair("plus", " + "), make_pair("minus", " - "),
        make_pair("times", " * "), make_pair("divided", " / "),
        make_pair("negative", "-")
    };
    return is_match(ops, sizeof ops / sizeof ops[0], term, val);
}

bool is_degree(string const& term, string& val) {
    pair<string, string> deg[] = {
        make_pair("squared", "^2"),
        make_pair("cubed", "^3"),
        make_pair("quartic", "^4")
    };
    return is_match(deg, sizeof deg / sizeof deg[0], term, val);
}

bool is_literal(string const& term, string& val) {
    string words[] = {
        "one","two","three","four","five",
        "six","seven","eight","nine",
        "ten","eleven","twelve","thirteen","fourteen","fifteen",
        "sixteen","seventeen","eighteen","nineteen",
        "twenty","thirty","forty","fifty",
        "sixty","seventy","eighty","ninety"
    };
    vector<pair<string, string>> literals;
    for (size_t x = 1, k = 0; x < 100; /* see body */) { …
Luther von Wulf 7 Light Poster

It depends on the library, but GUI libraries are complex in their nature.

Luther von Wulf 7 Light Poster

if you want to make a gui program that is not all DOS, and command prompt, then why use C++

You can say the same about any other programming language. Java for example has a GUI library, but it is not part of the language. You still have to learn the library on top of the language. It is the same with C++. The only difference is the GUI library is not packaged with the standard library.

Luther von Wulf 7 Light Poster

What are some good exercises for an experienced programmer new to C++? I have found lists and suggestions on the web, but they are always simple or I have already completed them in other programming languages like C or Basic. Something that will help with learning modern C++ is best.

Luther von Wulf 7 Light Poster

Zip is a compression format. You must decompress the zip files to see the contents. The process will differ with your OS. On my Windows OS, I use WinRAR and extract to a folder.

Luther von Wulf 7 Light Poster

What kind of help do you need? Are there errors that you do not understand?

Luther von Wulf 7 Light Poster

Did you prefix the name with the namespace?

std::nth_element(minRollArray, minRollArray+n, minRollArray+numSets);
Luther von Wulf 7 Light Poster

but they are zip files?

Yes. Unzip them. :) The books are HTML files and the code are C++ files.

Luther von Wulf 7 Light Poster

Sure, the only problem is that most compiler right now do not support the auto keyword

This is not a problem with the code. This is a problem only if the code is cut and pasted without understanding how it works. That is always a bad idea. :) And the best way to promote C++0x is to use it and teach it, yes? That is progress.

Luther von Wulf 7 Light Poster

1) Get a IDE, I suggest one of these, codeblocks or visual studio 2008.

Visual C++ 2010 is better because it has parts of the newest C++ and the IDE is much improved. Visual C++ 2008 is still good, but if old projects do not need to be maintained then the latest version is better.

Learning C++ is easier now because there are so many free options. These two ebooks are good and go very far.

Luther von Wulf 7 Light Poster

Looping over the string keep in mind that the code is looking for a single instance of the character type. Avoid breaking the loop until the end. Your code does not work because the first loop in verifyPass returns false if *any* of the characters in the whole string is not lower case.

One loop can be used with flags and then the flags are tested after the loop covers the whole string.

bool verify_pass(string const& pw) {
    bool length = pw.size() >= 6 && pw.size() <= 10;
    bool upper = false, lower = false, digit = false;
    if (length) {
        for (auto x = pw.begin(); x != pw.end(); ++x) {
            if (isupper(*x))
                upper = true;
            else if (islower(*x))
                lower = true;
            else if (isdigit(*x))
                digit = true;
        }
    }
    return length && upper && lower && digit;
}

This function works for a whole string test, but more detail for the reason why the stirng failed is good idea. That is an exercise for you now that the problem is solved. :)

p.s. It is not a good idea to limit the upper length of the string because longer passwords are more likely to be secure than shorter passwords. A lower limit is good.

Luther von Wulf 7 Light Poster

I thought ffgets second argument would limit the input, but it doesn't. Any help is appreciated.

fgets *does* limit the input. But only for the buffer argument to fgets. To print an error if there is more input than the buffer can hold, check for a new-line character at the end of the buffer. If there is not one new-line then there are more characters in the input stream.

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

void main() {
    char buffer[10+2]; // 10 data + new-line & nul
    if (fgets(buffer, sizeof(buffer), stdin)) {
        if (buffer[strlen(buffer)-1] != '\n')
            fprintf(stderr, "Input string too long\n");
        else
            fprintf(stderr, "Input OK\n");
    }
}