mcriscolo 47 Posting Whiz in Training

OK,

First, you set the pointers up - one for the input string (p), and one for the output string (p3).

while ((p2 = strstr(p, target)) != NULL)

This is to get "p2" to point at the start of the string you want to replace. We do it this way so we can put it in a loop (instead of while ((p2 = strstr(inputstr, target)) != NULL) But, before you can copy the replacement string to the output string, you have to copy all of the characters from the input string that came *before* the string you want to replace. That's what this complicated-looking piece of code does:

strncpy(p3, p, (strlen(p) - strlen(p2)));

"strncpy" copies a string from (in this case) "p" to "p3", but only for a number of characters specified in the 3rd parameter. The third parm in this case is the length of the input string (p) minus the length of the string from the match position. The difference is the length of the string *before* the match position. We copy that to the output string, then push the pointer to the output string up by that same amount.
Now, we copy the replacement string to the output, and push the pointer up by the length of the replacement string:

// Copy the replacement string to the result
strcpy(p3, replacestr);
// Increment the result pointer 
p3 += strlen(replacestr);

Now, we move up the pointer in the input string to the match location …

mcriscolo 47 Posting Whiz in Training

To clarify on stillearning's point: you will have to create a new string that will be the result of the string replacement. You have some issues to look out for - if the replacement string is larger than the target string, or smaller. Pseudo code would look something like

p = inputstr;
p3 = newstr; // You'll have to allocate space for this!
while ((p2 = strstr(p, target)) != NULL)
{
    // Copy all characters up to the match point
    strncpy(p3, p, (strlen(p) - strlen(p2)));
    // Increment the result pointer
    p3 += (strlen(p) - strlen(p2));
    // Copy the replacement string to the result
    strcpy(p3, replacestr);
    // Increment the result pointer 
    p3 += strlen(replacestr);
    // Increment the target pointer past the matched string
    p += (p2 + strlen(targetstr));
}

// handle the end-bound case
strcpy(p3, p);

All the "p" variables are char *.

Hope this helps!

mcriscolo 47 Posting Whiz in Training

Jennifer,

If you still need an answer on this, here it is:

Add a ContextMenuStrip to the form and put some elements in it, then add an event handler for the "MouseDown" event, and add the following code:

if (e->Button == System::Windows::Forms::MouseButtons::Right)
{
    contextMenuStrip1->Show(e->X, e->Y);
}

That should pop the menu when you right-click on the form.

mcriscolo 47 Posting Whiz in Training

A few suggestions:

void setVoltageValues(float fVcc, int iTblkLoopEnb, double dBlah);

Or:

void setVoltageVcc(float fVcc);
void setVoltageTblkLoopEnb(float iTblkLoopEnb);
void setVoltageBlah(double dBlah);

However, if you change your struct, the methods above have to change.

Or:

void setVoltageValues(struct VoltageValues *pVV);

Pass in a pointer to a pre-initialized VoltageValues struct and assign the internal members to the corresponding ones in the class variable.

Whichever you feel will be easier to maintain and understand; any of the ways will work.

mcriscolo 47 Posting Whiz in Training

That's just a formatting issue. You want to insert a line to write out another carriage return when you are at the bottom of the main while loop - just before you are going to read in another line from the input file.

Also, make sure you're consistent with your variable names. You really don't need a variable for "romNum", since you are outputting the result a-Roman-numeral-at-a-time as you go through your while loops.

mcriscolo 47 Posting Whiz in Training

This line:

fin >> romNum >> araNum ;

It will try to pull in 2 numbers at once from your input file. It should be:

fin >> araNum ;

Since you are reading in the Arabic number. Then convert that to Roman.

mcriscolo 47 Posting Whiz in Training

In the "Daily_Average" function, you set the variable "j", like this:

int j = day-1;

but then in the loop, you do this:

for (j = 0; j < 3; j++)

thereby resetting the value of "j" back to zero.

Initialize a new variable at the top of the function, like this:

int k = day-1;

Then set your loop, like this:

for (j=k; j<3; j++)

And you should be all set.

mcriscolo 47 Posting Whiz in Training

Have you dumped/debugged the contents of the "full_name" variable to ensure that it looks the way you expect? Be sure there are no hidden carriage returns or other garbage that would possibly cause your comparison to fail.

mcriscolo 47 Posting Whiz in Training

There are actually 2 things - 1 correctly posted by Sci@phy. You must escape the backslash, so you would enter "C:\\*".

The other is that the function FindFirstFile is expecting a wide character string as input. The cast was set correctly; however, you need to annotate the string constant so it will be interpreted as a wide character string, like this:

HANDLE hFind = FindFirstFile((LPCWSTR) L"C:\\*" , &findFileData);

Notice the "L" in front of the string. This will work.

mcriscolo 47 Posting Whiz in Training

You need to increment the "cntr" variable somewhere in your loop. You are repeatedly checking the first item of the array.

Just for completeness, you know if someone types in "fred smith" instead of "Fred Smith", you will hit the end of the list without finding the item.

mcriscolo 47 Posting Whiz in Training

Unfortunately, it's not that simple.

First, be sure you change the "View" property of the ListView to "Details" so you will see your columns.

Next, you need to add a ListViewItem to a ListView, like this:

ListViewItem ^li = gcnew("Col 1 Value");
li->SubItems->Add("Col 2 Value");
listView1->Items->Add(li);

You can keep calling li->SubItems->Add("...") for as many columns you need.

mcriscolo 47 Posting Whiz in Training

The idea is generally there; however, there are some things you need to look at:

1) Reading & writing the entire object out - that can be problematic. What if, the first time you write out a "houses" object, the "furnished" string is set to "no"? Then the second, it's set to "yes"? The object may not look like you expect internally. Better to write each variable out knowing what length each is:

out.write((char *)&house_number, sizeof(int));
...

Then, in your display_house() function, do the same when reading in:

in.read((char *)&house_number, sizeof(int));
...

2) your total record size (needed for the seekg operation) will now no longer be sizeof(h) , but the combined size of each of your elements (allow 4 bytes for the string, since you are storing "yes" or "no").

3) Internal use of the object you're defining. I guess it can be OK, but not like this (in the housewrite() method):

houses h;
...
get_house();
out.write((char *)&h,sizeof(h));
out.close();

The method "get_house()" loads the data into the object variables of the current instance, but then you attempt to write out "h" - an uninitialized local version of your object. You'll be fixing that anyway if you follow the steps in 1 & 2, above.

4) The method you're using to locate records is a combo of relative record number, and "house_number" the user enters, which can be easily broken. You use the house_number to perform the seek, then check the record you read …

mcriscolo 47 Posting Whiz in Training

Thanks - glad I could help!

mcriscolo 47 Posting Whiz in Training

Actually, the code you wrote should have looked something like (assuming other errors were corrected - code below is not correct!):

if (user_selection < Lasagna)
[INDENT]cout << "Incorrect please try again";[/INDENT]
else 
[INDENT]cout << "Good job! You guessed my favorite food!";[/INDENT]
}while (user_selection != Lasagna);

That's why you use enums in the first place - to make the code more readable (rather than having a bunch of numbers).

However, CoolGamer48 is correct - you need to translate the user's input (which is a string of characters) into an instance of a "food" variable which you could then use in the comparision. The wordy (but effective) way is:

string user_selection;
        food eChoice;
        do{
                cout << "Pick a Food: ";
                cin >> user_selection;
                if (user_selection == "Pizza")
                {
                        eChoice = Pizza;
                }
                else if (user_selection == "Lasagna")
                {
                        eChoice = Lasagna;
                }
                else if (user_selection == "Chips")
                {
                        eChoice = Chips;
                }
                else
                {
// Bad assumption here, but it's an example
                        eChoice = Burrito;
                }
}
                if (eChoice < Lasagna)
                cout << "Incorrect please try again";

                else

                cout << "Good job! You guessed my favorite food!";
                }while (eChoice != Lasagna);

A more elegant approach could be to use a STL Map (type <string, int>) to load up a container of the string values and the associated integer values. Take the user's input, whack it up against the map and get the int value, which you then could use enum tags for the comparison.

mcriscolo 47 Posting Whiz in Training

One way I might think of doing this is:

1) develop an object (call it "ColumnDef") to represent a single value of one of your columns. It would contain a type property (int, string, etc), and a buffer to hold the data.
2) develop a C++/STL Map of these "ColumnDefs". This would represent a row in your table. The map would let you associate a column name with a "ColumnDef" entry.
3) develop an array of the Map objects.

That, in essence is the database. When looking for matching values of a SQL-like clause, you would start at the top of the array, evaluating each "row" by checking for a map entry matching a column in the query.

You would then build another structure like above to hold the results (an array of Map objects, each entry in the Map is a ColumnDef). This is because for the projection operation, you need to remove any possible duplicates from the results. So, you would have to also search the result structure during the insertion to ensure a duplicate is not being added.

Finally, you print out the contents of the result structure which (hopefully!) contain the actual results of the query.

Hopefully this helps!

mcriscolo 47 Posting Whiz in Training

You can use memcpy to copy the various parts of one variable (or buffer) to another.

Assuming that tmpbuf has your data (I assumed is was defined as "char *tmpbuf):

char tmpbuf1[2];
char tmpbuf2[2];

memcpy(&tmpbuf1, &tmpbuf[0], 2);
memcpy(&tmpbuf2, &tmpbuf[2], 2);

The variables tmpbuf1 an tmpbuf2 will contain the data split as you described.

mcriscolo 47 Posting Whiz in Training

Glad I could help (though I'm confused about the error; I pasted that code directly from my project..)

As far as 3 text boxes are concerned, you'll have to manage them yourself. If you change the example to use textboxes instead of labels (assuming the text boxes are named "txtHour", "txtMinute", "txtSecond"), the code in the timer_Tick routine would look something like:

int iHour = Convert::ToInt32(txtHour->Text);
int iMinute = Convert::ToInt32(txtMinute->Text);
int iSecond = Convert::ToInt32(txtSecond->Text);
iSecond--;
if (iSecond == -1)
{[INDENT]iSecond = 59;
iMinute--;
if (iMinute == -1)
{[INDENT]iMinute = 59;
iHour--;
if (iHour == -1)
{[INDENT]// Ending condition - turn off the timer
iHour = 0;
iMinute = 0;
iSecond = 0;
timer1->Enabled = false;[/INDENT]
}[/INDENT]
}[/INDENT]}
txtHour->Text = iHour.ToString();
txtMinute->Text = iMinute.ToString();
txtSecond->Text = iSecond.ToString();

Note that once you start letting users input the values, you will have to edit/validate them to ensure they don't enter trash characters - in the above case, the "ToInt32" functions will dump if you hand them trash. Also, you'll want to make sure they enter valid values, such as limiting the minutes and seconds to a range of 0-59.

Let me know if you have any more questions.

Wiki_Tiki commented: Helped extremely well with making a timer. Explained code, gave understandable snippets. +1
mcriscolo 47 Posting Whiz in Training

I'll start from the top:

Open a new C++ "Windows Forms" project. On the main form, drag a Label Control and a Timer Control. Change the name of the label control (clicking on the label, then going to the property sheet) to "lblCount". Change the text property of the Label control to "30". Now, click on the Timer control. Again, using the property sheet, change the interval to 1000 (its in milliseconds), and ensure that the "Enabled" property is false.

Now, we have to mod the code. In "Form1.h", add the following line in the constructor for Form1:

this->timer1->Enabled = true;

This will start the timer, and it will fire every 1000 ms (1 sec). Now, go back to the form designer. Double-click on the Timer control. It will take you into the code into a newly-created member function named "timer1_Tick". Inside this function, add the following code:

int iCount = Convert::ToInt32(this->lblCount->Text);
iCount--;
if (iCount == 0)
{
[INDENT]this->lblCount->Text = "Done!";
this->timer1->Enabled = false;[/INDENT]
}
else
{
[INDENT]this->lblCount->Text = iCount.ToString();[/INDENT]
}

When run, the form will appear, countdown from 30, and when it hits zero, it will display "Done!" and turn off the timer.

Note there are obvious edit checks that are skipped, like putting a value other than "30" in for the label will cause the program to bomb.

Let me know if this works for you.

mcriscolo 47 Posting Whiz in Training

First, if you want an IDE like Eclipse for C++ on Windows, you can do a couple of things: 1) use Eclipse - it has a C++ developers perspective you can use to code in C++. It can be set up to use Microsoft's C++ compiler or GNUs (via minGW or Cygwin), or 2) Microsoft has a free version of it's C++ IDE (Visual C++ Express 2008, available here).

Microsoft's Visual Studio has the same sort of stuff that Eclipse has, as far as syntax coloring for code, and what Microsoft calls "intellisense" - where you hit the dot or (->) and a list of methods and properties shows up for the object you're using.

As far as garbage collection is concerned, it depends on what environment you use. If you use the .NET environment (managed C++, C# or VB.NET), you do get garbage collection, but most game programming is done in unmanaged C++ (like the old days). No garbage collection with unmanaged C++ - that's your job.

Help if you get stuck - a lot of folks use C++ - shouldn't be an issue.

Libraries - there's a game developer kit called DarkGDK that is free-to-use (check site for details!) library that wraps up a lot of "standard" gaming code, and it works with Visual C++ Express 2008. Their site is here. The DarkGDK uses DirectX for the low-level graphics stuff.

Or you can use OpenGL. There's a free library …

mcriscolo 47 Posting Whiz in Training

Jennifer,

OK, here's a complete rundown:

I'm assuming you are working with a "Windows Forms" app. If you call the form that you get when you start the project "Form1", this code will show you how to open a new form, and close it by pressing a button on Form1.

First, add another Windows form to the project; call it "Form2".

In that form, add a function, called FormClose10:

public:
void FormClose10()
{
[INDENT]this->Close(); // CoolGamer48 is correct, you can just say "Close()" if you want - I'm wordy...[/INDENT]
}

In the Form1 designer, add 2 buttons, one labeled "Open" and another labeled "Close".

In the Form1.h file, put the following code:

#include "Form2.h"

right after the "#pragma once" at the top of the file.

In Form1.h, inside the class definition, add the following code:

private:
[INDENT]Form2 ^myForm2; // this is different than what I first told you -- sorry

[/INDENT]

In the "Open_Click" routine, add the following code:

myForm2 = gcnew Form2();
myForm2->Show();

In the "Close_Click" routine, add the following code:

myForm2->FormClose10();

That should do it. When you run the program, Form1 will come up with 2 buttons; press "Open" and Form2 should appear... press "Close" on Form1 and Form2 should disappear.

If you have any problems, let me know. I can send a C++ project to you that has this code working if you like.

mcriscolo 47 Posting Whiz in Training

Jennifer,

OK, a few things:

In Form1, if you don't want to, you don't have to pass "sender" and "e" to the public function. So the function declaration in the form can just be:

public void FormClose10();

In Form2, you will need an instance of Form1 (I'm paraphrasing from your first post, where you declared a pointer to the form), something like this:

In Form2:

Form1 *myForm1 = new Form1();
...
<do stuff with the Form1>
...
myForm1->FormClose10();

The key is that you have to have a reference variable (in this case "myForm1") in order to call the public function.

In this example:

Form1::FormClose10();

This is trying to call a static version of the function, which is not what you want. The form has to be instantiated, which is what the call:

Form1 myForm1 = new Form1();

does. Then you can monkey with it.

Let me know if I can be of more help.

mcriscolo 47 Posting Whiz in Training

Jennifer,

I believe what you want is a public function on Form2's class. For example, you can make a public function called "CloseForm" on Form2. Inside "CloseForm" you would call the close function:

this->Close();

Then, from Form1, when your button is pressed, you would issue the call:

form2->CloseForm();

Hope this helps!

mcriscolo 47 Posting Whiz in Training

The timer control allows you to specify a callback function that will get control whenever the timer fires. Usually when you double-click the control on the form, it will build the function stub for you.

Once in the callback, you can grab the contents of the label control, convert to an integer, subtract the value and put it back into the label control (converting it back to a string).

-Mike