nucleon 114 Posting Pro in Training

So you mean something like this?

class ArtClass {
};

class School {
    ArtClass* m_artclass;
public:
    School(ArtClass* artclass) { m_artclass = artclass; }
};

class Main {
    School*   m_school;
    ArtClass* m_artclass;
public:
    Main() {
        m_artclass = new ArtClass();
        m_school = new School(m_artclass);
    }
    ~Main() {
        delete m_school;
        delete m_artclass;
    }
};
nucleon 114 Posting Pro in Training

If "inlining the spezialized member functions" works, what's wrong with that solution? The only other thing I can think of (if I understand the problem) would be to put those functions in an object file of their own.

nucleon 114 Posting Pro in Training

Your code is spaced all over the place. Mixed spaces and tabs?

If your basic question is how to initialize reference members of a class, you do it like this:

class Class { /*...*/ };

class Class2 {
    Class& m_class_ref;
    //...
public:
    Class2(Class& class_ref);
    //...
};

Class2::Class2(Class& class_ref) : m_class_ref(class_ref) {
    //...
}
nucleon 114 Posting Pro in Training

I don't see why it's a segfault, but you are using compare incorrectly. Remember that it returns 0 if the strings are equal, so you want to keep looping while it is not 0. You are doing the opposite, looping as long as the string IS "cls". You could just use != if you want.

do {
    inFile >> junk;
} while (junk != junk1);
nucleon 114 Posting Pro in Training

at() cannot be used with C-style arrays, but can be used with vector and string. You would want to change your data structure from string *world; to vector<string> world; . You could use a vector of vectors, instead.

nucleon 114 Posting Pro in Training

Remember to always look for punctuation errors near the error line. Here you forgot the semicolon after enum cmp_t (after the closing brace).

nucleon 114 Posting Pro in Training

The problem with your menu is that you're reading into a char but testing against an integer. Change gmOption to an int.

I'd finish the rest of the program first before worrying about how you will integrate cheats into it.

BTW, I'd make some consts for the colors, make the console handle global, and use a function to set the color, like so:

HANDLE hOut;

const WORD WHITE = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
const WORD BWHITE = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN;
const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN;
const WORD BYELLOW = BACKGROUND_RED | BACKGROUND_GREEN;
//etc.

void color(WORD col) {
    SetConsoleTextAttribute (hOut, col);
}

// Call it like this:
color(WHITE|BYELLOW);
nucleon 114 Posting Pro in Training

No problem. I must have posted at the same time as you.

You might want to put explicit exits for each child to make sure none of them is executing more code than you want.

BTW, 1 is not technically prime!

nucleon 114 Posting Pro in Training

Think about it for awhile, then check out wikipedia.

nucleon 114 Posting Pro in Training

So the prime number file is correct at school as well as on ubuntu? Only outputing to standard output (reading from the perfectly correct file) is not working???

I would've imagined that the numbers from the different children would get mixed up in the file if you don't use file-locking. If one wrote 135 and another wrote 246 you might get 132465. At least that's how it seems to me, but I must be missing something if it works at school.

nucleon 114 Posting Pro in Training

Try g++ (c++ compiler) instead of gcc (c compiler).

nucleon 114 Posting Pro in Training

> it takes so much of time to find a number greater
> than searching number

That's the heart of the problem. How do you decrease that time? You definitely don't want to do a linear search!

I guess I understand the "infinity" stuff. It means that you can access any index whatsoever without an error. This could be implemented as a function that returns the element value for indices up to n-1 but returns "infinity" (say max int) otherwise.

The question is basically "how do you do a binary search (or similar) on an infinite array"? Obviously you can't start in the "middle", so you need to consider other options.

nucleon 114 Posting Pro in Training

Binary trees have 2 branches (max) at each node. To store an arbitrary number of links you need an expandable data structure, like a vector.

nucleon 114 Posting Pro in Training

Your bounds-checking will not work. It isn't a matter of whether row or col are already out-of-bounds, but that they may become so after you add or subtract one to/from them. You could make a function called checkForNeighbor with your bounds-checking code in it and use it like this in countNeighbors: if (checkForNeighbor(newworld, row - 1, col - 1)) n++; To check for '1' instead of true, simply replace everywhere it says true in countNeighbors with '1' (including the single quotes).

Presumably, iterateGeneration should be calling countNeighbors. And you should really clean up those globals. Also, since this is a C++ program, shouldn't you be using a class?

nucleon 114 Posting Pro in Training

Two obvious problems in countNeighbors:

  1. You are not bounds-checking (row or col plus or minus one may be out-of-bounds).
  2. You are testing against true when you've loaded your "array" with '0' and '1' (i.e., change true to '1')

Other than that you need to post all your code (can't be much more).

nucleon 114 Posting Pro in Training

In c:\test.bat try c:\windows\system32\msg * text (or whereever it is on vista). That should work. Then mark this thread as solved.

nucleon 114 Posting Pro in Training

I think you'll need something like this:

typedef vector<Word*> WordList;
class Word : public string // either inherit from string or contain one
{
    vector<WordList*> v;
public:
    ...
};

This amounts to a vector of vectors, which I think you may need.

nucleon 114 Posting Pro in Training

So c:\test.bat has something like "echo hello world" in it??? If so then it seems to be working.

nucleon 114 Posting Pro in Training

I was thinking she needed something more complicated too, but now that I look again, maybe she is looking for an n-ary tree. Taking her example, starting with a given root word (e.g. "cat"), generate all words with one letter different:

* for each letter in word
  * go through all possible letters
  * if you form a word already in the tree, store a pointer
    to it
  * add new words (found in dictionary) to the list for
    this tree node

Then go through all new words, changing only letters that haven't yet been changed, checking for the words' preexistence in the tree, checking if it's a word (in the dictionary), adding it if it is.... This would create an n-ary tree, perhaps with some extra structure.

Maybe that's the kind of thing she's looking for.

nucleon 114 Posting Pro in Training

How can 8 be fine when the string you give in demonstration is 15 characters long? Also you're calling strftime with a maximum of 80. Making the hwnd global works for me:

#include <windows.h>
#include <ctime>
#include "resource.h"

static bool keepRunning = true;
static HANDLE hThread = NULL;
static void run();
static void end();
static DWORD WINAPI ThreadTime(LPVOID lpParam);

char strCurrentTime[80]; // change back to extern if needed

HWND hWndCurrentTime;
HWND hWnd;
HINSTANCE hInst;
LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine, int nCmdShow)
{
  DialogBox(hInstance, MAKEINTRESOURCE(IDD_CONTROLS_DLG), hWnd,
              reinterpret_cast<DLGPROC>(DlgProc));

  hInst = hInstance;

  return 0;
}

LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{

//  char strMeetingTime[8], strStartTime[8], strBreak1Start[8], strLunch[8],
//         strBreak2Start[8], strLeaveTime[8],  strLateBreak[8], strTime[10];

//  HWND hWndMeetingTime, hWndStartTime, hWndBreak1,
//                hWndLunch, hWndBreak2, hWndLeaveTime, hWndLateBreak;

  hWndCurrentTime = GetDlgItem(hWndDlg, IDC_CURRENT_TIME);
/*  hWndMeetingTime = GetDlgItem(hWndDlg, IDC_MEETING_TIME);
  hWndStartTime   = GetDlgItem(hWndDlg, IDC_START_TIME);
  hWndBreak1      = GetDlgItem(hWndDlg, IDC_BREAK1);
  hWndLunch       = GetDlgItem(hWndDlg, IDC_LUNCH);
  hWndBreak2      = GetDlgItem(hWndDlg, IDC_BREAK2);
  hWndLeaveTime   = GetDlgItem(hWndDlg, IDC_LEAVE_TIME);
  hWndLateBreak   = GetDlgItem(hWndDlg, IDC_LATE_BREAK_BTN);*/

  switch(Msg)
  {
    case WM_INITDIALOG:
      run();  // start thread for showing current time
/*      SetWindowText(hWndMeetingTime, "");
      SetWindowText(hWndStartTime, "");
      SetWindowText(hWndBreak1, "");
      SetWindowText(hWndLunch, "");
      SetWindowText(hWndBreak2, "");
      SetWindowText(hWndLeaveTime, "");*/
    return TRUE;

    case WM_COMMAND:
      switch(wParam)
      {
//        case IDC_LATE_BREAK_BTN:
          // Start a 15 minute timer

//        return TRUE;

        case IDCANCEL:
          end();
          EndDialog(hWndDlg, 0);
        return TRUE;
      }
    break;
  }

  return FALSE;
}

static void run()
{
  DWORD dummy;
  hThread = CreateThread(NULL, 0, ThreadTime, NULL, 0, &dummy);
}

static void end()
{
  keepRunning = false;
} …
nucleon 114 Posting Pro in Training

This should probably be 80, not 8. extern char strCurrentTime[8];

nucleon 114 Posting Pro in Training

Try making hWndCurrentTime global. Then change strCurrentTime (in ThreadTime) temporarily to "xyz" and see if it displays. If not, then you'll need to do what AD suggests.

nucleon 114 Posting Pro in Training

Sounds like it's running a test.bat. Is that's what's in the at c:\ or is there another in the current directory?

nucleon 114 Posting Pro in Training

Depends on the format of the matrix in the file. Is it text or binary. If it's text, can you cut and paste it?

nucleon 114 Posting Pro in Training

Yes, you need a loop in main. main should not (as far as I know) be called recursively. Since it's simple tail recursion, it's possible in this case that it would be optimized away. But it's still not a usual idiom and not necessary. In general, your main and overall program structure are a little messy. What about a structure like this (still using C++ in the procedural style):

const char* introduction = "howdy";
const int NCHILDREN = 25;
const int MAXMUTATIONS = 3;

int main()
{
    srand(time(0));
    string goal;
    cout << introduction << endl;
    while (getString(goal)) { // getString returns false on "q"uit
        string start = rndString(goal.size());
        cout << s << endl;
        cout << evolve(start, goal);
    }
    return 0;
}

int evolve(string str, string goal)
{
    string children[NCHILDREN];
    int nGeneration = 0;
    while (str != goal) {
        reproduce(str, children);
        str = select(children, goal);
        nGeneration++;
    }
    return nGeneration;
}

void reproduce(string str, string children[])
{
    for (int i = 0; i < NCHILDREN; i++) {
        children[i] = str;
        mutate(str);
    }
}

// mutate will even mutate correct characters (see * below)
void mutate(string str)
{
    int nMutations = rand() % MAXMUTATIONS + 1;
    for (int i = 0; i < nMutations; i++) {
        str[rand() % str.size()] = rndChar();
    }
}

That's basically the heart of your code, but much cleaner looking. (I haven't run it, yet, so no guarantees. Note that it doesn't bother to save all the "parents".)

And yes, a C++ programmer would probably define at …

nucleon 114 Posting Pro in Training

I'm trying out Code::Blocks. It's pretty nice!
Try this code. I've included instuctions on how to link it with ole32 in Code::Blocks. Also, it shows the formatted error message in a message box.

#include <windows.h>
#include <objbase.h>

// Link with ole32. In CodeBlocks, add "ole32" (no quotes) to
// Project/Build options/Linker settings/Link libraries

void showError(char *msgin)
{
    char *msgbuf, *displaybuf;
    DWORD dw = GetLastError();
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (char*)&msgbuf, 0, NULL);
    displaybuf = (char*)LocalAlloc(LMEM_ZEROINIT,
        strlen(msgbuf) + strlen(msgin) + 40);
    wsprintf(displaybuf, "%s failed with error %d: %s",
        msgin, dw, msgbuf);
    MessageBox(NULL, displaybuf, "Error", MB_OK);
    LocalFree(msgbuf);
    LocalFree(displaybuf);
}

int main(int argc, char *argv[])
{
    SHELLEXECUTEINFO sei = {sizeof(sei)};

    CoInitializeEx(NULL,
        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    sei.lpVerb = "runas";
//    sei.lpVerb = "open";
    sei.lpFile = "c:\\test.bat";
//    sei.lpFile = "c:\\windows\system32\msg.exe";
    sei.nShow = SW_SHOWNORMAL;
//    sei.lpParameters = "";
//    sei.lpDirectory = "";

    if (!ShellExecuteEx(&sei)) showError("ShellExecuteEx");

    CoUninitialize();

    return 0;
}
nucleon 114 Posting Pro in Training

About variable names, Stroustrup makes a good point saying that as the scope gets larger the names should get bigger. If you plan on doing any Windows API, it's nice to distinguish your functions by starting them with a lower-case letters, since the API always (or at least almost always) uses mixed case starting with uppercase.

Anyway, you are coding in the procedural mode, making your program look more like C than C++. A couple of points on your C-like program. You have a constant 8 (sometimes appearing as 7) throughout your program. So either: #define SIZE 8 /* Hard-core C */ const int SIZE = 8; // C++ You could get rid of other constants similarly, and calling main recursively to go again is probably not the best idea. Put the quit option as number 3 in your main menu (you could exit(0) there and use an ininite loop in main for now at least).

So your decision now is whether to learn pure C first or whether to go straight to C++.

nucleon 114 Posting Pro in Training

You're missing "AltMoney::" in the definition of read_money; and it should be putting it's input into "dollars" and "cents" (after validation). Also change the return type to void (in definition and declaration).

// change definition of read_money to
void AltMoney::read_money()

// Also, find and delete this line (just above main):
AltMoney read_money();

// main would go like this (no need for d and c in main):
     AltMoney m1;      // create object
     m1.read_money();  // read value
     cout << "The first amount is:";
     m1.display_money();
     AltMoney m2;
     m2.read_money();
     cout << "The second amount is:";
     m2.display_money();
     AltMoney sum;
     sum = add(m1,m2);
     ...
nucleon 114 Posting Pro in Training

First of all, this is an excellent effort and an interesting program. Here are some suggestions.

  • Give the user the option to go again.
  • Use C++ style includes: cstdio, cstdlib, etc.
  • Never let a line go over, say, 78 columns. (Definintely not over 80.)
  • Splitting string constants across lines can be done like this:
    cout << "\nUpper and lower case letters, spaces, "
                    "and common punctuation are allowed."
                    "\nInput target sentence:  ";

    As noted by death_oclock, this mechanism is why you didn't get the double-quotes you wanted around ancestor (and no syntax error either).

  • It's best to have an overall program description at the top. Since your intro message is a good summary, you could put something like this at the top of your program.
    // Sentence Evolver by Me & Dawkins
    
    const char* Description =
    "This program attempts to demonstrate the fact\n"
    "that natural selection is not random chance, but a chance-\n"
    ...
    "\"ancestor\" sentence of the length of the target string.\n"
    ...;

    Then get rid of the function "introduction" and replace the call to it by cout << Description;

  • Use \n for newline when there's already a double-quoted string right there. E.g:
    cout << "Ancestor:  " << initial << endl << endl
              << "Enter to continue." << endl;
    // could be:
        cout << "Ancestor:  " << initial << "\n\nEnter to continue.\n";
  • In general, I would rather see the comments before their target (rather than after or on the same line). I suppose that's just …
nucleon 114 Posting Pro in Training

I think it's just the X in your input file (should be a 1 maybe?). Your expected output is unexpectedly short, having only nine members.

nucleon 114 Posting Pro in Training

Sadly I haven't used unix in many years, so hopefully a real unix person will come along to help you. A couple of points, though.

You should pass the base pointer of the 2-element int array to pipe. Also, try cleaning up your error handling, something like this, although I haven't included any cleanup like closing fd's.

void die(const char *msg)
{
    perror(msg);
    exit(1);
}
...
    if (pipe(toServer) == -1) die("pipe to");
    if (pipe(fromServer) == -1) die("pipe from");
    if ((pid = fork()) == -1) die("fork");
    // use same err-handling method elsewhere too

You need to remember when to pass the value and when the address to the scanf functions:

// You need to add an ampersand here since fnum is a float.
    sscanf(buffer, "%f", &fnum);
...
// And remove one here, since id is a string.
    fscanf(finput, "%s %d %f",
           &r[i].id, &r[i].odometer, &r[i].gallons);

Try not closing STD_OUTPUT and STD_INPUT for now; I don't see why that's necessary in this particular case (although maybe it is). And presumably you should be saving and using the file descriptors returned from dup:

if ((fd = dup(fromServer[0])) == -1) die("dup fromServer");

I'm already overstepping my knowledge so I'll stop there.

nucleon 114 Posting Pro in Training

You do not want to free temp there. Remember that you do not free pointer variables, but the memory that they point to. In this case, you do not want to free the memory that temp points to because you still have a pointer (*head) pointing to it and the memory is still being used.

free(xxx) is used when you actually want to delete the memory (often called the object) that the pointer points to.

nucleon 114 Posting Pro in Training

You need to clear the flags before the seek.

file.clear();
    file.seekg (0, ios::beg);
nucleon 114 Posting Pro in Training

No problem. It's noteworthy that this bug involved casting. Remember to cast only when absolutely necessary since subverting the type system can be dangerous. In this situation, if you declare NUM_BUCKETS as an unsigned and return an unsigned, there's no need for a cast at all.

nucleon 114 Posting Pro in Training

I don't remember if anyone's suggested initializing COM. Try this.

#include <iostream>
#include <windows.h>
#include <objbase.h>
// Link with ole32 (add -lole32 to the linker command line)


#define FILE "c:\\test.bat"
//#define FILE "c:\\windows\system32\msg.exe"

#define VERB "runas"
//#define VERB "open"


int main(int argc, char **argv[])
{
    SHELLEXECUTEINFO shExecInfo;

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
                         COINIT_DISABLE_OLE1DDE);

    shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
    shExecInfo.fMask = 0;
    shExecInfo.hwnd = 0;
    shExecInfo.lpVerb = VERB;
    shExecInfo.lpFile = FILE;
    shExecInfo.lpParameters = 0;
    shExecInfo.lpDirectory = 0;
    shExecInfo.nShow = SW_MAXIMIZE;
    shExecInfo.hInstApp = 0;

    if (!ShellExecuteEx(&shExecInfo))
        std::cout << "Error: " << GetLastError() << "\n";

    CoUninitialize();

std::cin.get();

    return 0;
}
nucleon 114 Posting Pro in Training

Presumably it has an empty environment, which means no path variable. So you will have to use the full pathname of msg. Something like: c:\windows\system32\msg

nucleon 114 Posting Pro in Training

Solved it! (About two seconds after my last post.)
The problem is in this line: return (static_cast<int>(h) % NUM_BUCKETS); You must remove the cast to int, since that may give you a negative number and therefore the mod will return a negative number, giving you an array subscripting error.

fusi0n423 commented: Great help this was really stumping me. +1
death_oclock commented: Nice effort, clever solution, very helpful! +4
nucleon 114 Posting Pro in Training

Hold that code! I put together the pieces you've posted so far and was able to generate an error with this: Hash h; h.insert("KSADLOP 033983h"); The error does seem to be in the hash function. In fact, it seems to be with this line since commenting it out causes the program to work: h = (h << 5) | (h >> 27); Does commenting it out cause your program to work?
Strangely, changing it to this works: h = (h >> 5) | (h << 27); This is a strange one. I'll keep thinking.

nucleon 114 Posting Pro in Training

Everything still looks fine. You'll have to attach your entire code.

nucleon 114 Posting Pro in Training

Try adding "pause" to the end of your test.bat.

nucleon 114 Posting Pro in Training

I noticed that a while back you tried calling cmd.exe with parameters, but your parameters were not correct. You pass a command to cmd.exe with the /c flag, so assuming test.bat is in the root dir, try something like this:

ShellExecute (NULL, "open", "cmd.exe", "/c test.bat", "c:\\", SW_NORMAL);

or this (modified from Comatose's last post):

int main(int argc, char **argv[])
{
      SHELLEXECUTEINFO shExecInfo;

      shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

      shExecInfo.fMask = 0; // NULL;
      shExecInfo.hwnd = NULL;
      shExecInfo.lpVerb = "runas";
      shExecInfo.lpFile = "cmd.exe";
      shExecInfo.lpParameters = "/c c:\\test.bat";
      shExecInfo.lpDirectory = NULL;
      shExecInfo.nShow = SW_MAXIMIZE;
      shExecInfo.hInstApp = NULL;

      ShellExecuteEx(&shExecInfo);

      return 0;
}
nucleon 114 Posting Pro in Training

This code also looks okay, although it is definitely a place where an exception can occur. The error must be in how you've added members to "dictionary". Is it properly initialized to NULLs? When adding members, are you setting "next" to NULL. Etc, etc, ....

nucleon 114 Posting Pro in Training

The code looks reasonable, except that "and"ing with 0x0fff and 0xffff does nothing in this situation (assuming 16-bit shorts). Removing those will change nothing, however. I would check the "answer" you've been given before going any further. Your code may be just fine.

As for test_crc, there is no reason for those params.

nucleon 114 Posting Pro in Training

There does not seem to be anything wrong with your code. In particular, I see nothing that can cause an exception in what you've posted.

nucleon 114 Posting Pro in Training

IVR: "Interactive Voice Response"
But what is a "car dial"?
How much C do you know?

nucleon 114 Posting Pro in Training

I see what you mean. Good point.

nucleon 114 Posting Pro in Training

It is incorrect to say that a is "converted" to a pointer. a simply is a pointer. That's what an array name is, a constant pointer to the first element.

nucleon 114 Posting Pro in Training

Splitting hairs somewhat further, a better formatting for the printf with the long string is:

printf("\nYou have entered an invalid integer.\n"
           "Please enter a number smaller or equal to 20:\n");

String literals separated only by whitespace are concatenated by the compiler. A useful fact.

nucleon 114 Posting Pro in Training

chars basically are bytes.
So you access them by subscripting the buffer: buffer[i]

nucleon 114 Posting Pro in Training

Inside the class, "a" is really just a pointer variable, which is usually the same size as an int, so that's why you get one.

Outside the class, "a" is a 3-element int array, so that's why you get 3.

Remember that C++ does not automatically know the size of an array that is passed to a function. You would normally pass the size as well.