mcriscolo 47 Posting Whiz in Training
mcriscolo 47 Posting Whiz in Training

zachattack05,

To answer your last question first - no, security and tech support issues are never unfounded. Once you deliver an application to a user, you have to support it. And you will also have to make sure that only authorized users access the system.

I may have misunderstood part of your explanation of the app - you will be delivering the "server" app to your customers? I was under the impression that the server would remain with you (or your company) and the clients would access it over the network. Of course, if you are packaging up this solution, then the decision to include or not to include a full-blown database is a big one.

If I also understand part of the use case for the clients, you would want to be able to access the "server" directly from programs like Word or Excel? Hmm... If I had to do that, I'd open the can of worms with the database. While there is a lot of management that comes with it, I still maintain that it would be easier and take less time than trying to develop a wire protocol mimic of SQL Server or ODBC. You could always lock down the security in the database, and also issue the standard warning that if the customer monkeys with the database that you're not responsible, blah, blah (even though you and I both know you really are... But maybe you can beat some support $$$ out of …

mcriscolo 47 Posting Whiz in Training

Other than the details you gave in your post (so I don't know the *real* complexity of your app, or your budgetary constraints), might I suggest that you actually convert the data for your app to use a database? That is (and again, I'm not privy to the reasons why a custom format may be needed), developing a pseudo-ODBC driver or a server process that mimics the wire protocol of SQL Server (TDS, or Tabular Data Stream) seems like a whole lot of work. The time you spend developing, debugging, and then maintaining such a construct seems way more than what it would take to convert your data to use a database.

If the clients expect a database, then give 'em a database.

That being said, if a database just isn't going to work for you, there are some open source projects you may be able to look at to "borrow" some code - FreeTDS (though that's mainly for Unix/Linux programs that need to access a SQL Server database; and it's in C), unixODBC is an ODBC driver/manager developed in C.

Since you mentioned C# (probably running on Windows), there is a free edition of SQL Server 2008 (Express Edition) - it has some limitations, but it may be something you can try out.

Check this link out http://www.thefreecountry.com/sourcecode/database.shtml for a list of database projects where source may be available.

Good luck!

kvprajapati commented: Good suggestion! +11
mcriscolo 47 Posting Whiz in Training

Put this into your "Clear" button's code:

dTable.Columns.Clear();  // Clears the column defs
    dTable.Clear();          // Clears the data

The dTable is what actually controls what the DataGridView displays. So, clearing this out corrects the issue.

mcriscolo 47 Posting Whiz in Training

Have you tried setting the "DataSource" property of the DataGridView to null?

tblAllEntries.DataSource = null;
mcriscolo 47 Posting Whiz in Training
mcriscolo 47 Posting Whiz in Training

Try this link:

http://www.switchonthecode.com/tutorials/csharp-tutorial-binding-a-datagridview-to-a-database

Looks to be a good example of exactly what you need.

mcriscolo 47 Posting Whiz in Training

This is going to sound like I'm being an a**, but I don't mean to be... sometimes it helps to just put stuff down on paper and visualize it.

Write 2 columns of ascending (sorted) numbers on the paper (you can use 10 values, but less will suffice for illustration). Have an arrow point to the top of the "a" (left) list, and another arrow point to the top of the "b" (right) list. You will single step through the values in the "a" list, comparing them to the values pointed to by the pointer in the "b" list. Set aside room for a result list (which is now empty):

Compare:
- If the pointer for the "a" list is past the end of the "a" array, write all the remaining values from the "b" list to the result list and exit.
or
- If the pointer for the "b" list is past the end of the "b" array, write all the remaining values from the "a" list to the result list and exit.

- If the "current" value in the "a" list is greater than the "current" value in the "b" list, write the "b" list number in the result list and move the pointer up in the "b" list. Go back to "Compare:"
- If the "current" value in the "a" list is less than the "current" value in the "b" list, write the "a" list number in the result list …

mcriscolo 47 Posting Whiz in Training

It looks like you may be off a node when you issue the delete.

Here's a console app that will do what you want - you can adapt the code as you see fit:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

namespace XMLDelete
{
    class Program
    {
        static string sXML = "<?xml version=\"1.0\"?><Security><User><Username>jon</Username><Password>khan</Password><UserFolder>aliHomeDIR</UserFolder></User><User><Username>bob</Username><Password>khan</Password><UserFolder>aliHomeDIR</UserFolder></User></Security>";

        static void Main(string[] args)
        {
            XmlDocument myDoc = new XmlDocument();
            myDoc.LoadXml(sXML);
            XmlNode nodeToDelete = null;
            XmlNode topNode = myDoc.SelectSingleNode("/Security");
            foreach (XmlNode UserNode in topNode.ChildNodes)
            {
                foreach (XmlNode kid in UserNode.ChildNodes)
                {
                    if (kid.Name == "Username" && kid.InnerXml == "jon")
                    {
                        nodeToDelete = UserNode;
                        break;
                    }
                }
                
                if (nodeToDelete != null)
                    break;
            }

            if (nodeToDelete != null)
            {
                topNode.RemoveChild(nodeToDelete);
            }

            System.Console.WriteLine("Edited XML: " + myDoc.OuterXml);
        }
    }
}
mcriscolo 47 Posting Whiz in Training

Is the data coming in to you sorted? Or, can you sort it?

If so, then you can use standard break totaling. That is, you have "holder" variables for the vendor and the budget period. Then you process each row of your set, totaling up the values for your financial fields until the budget period of the current record doesn't match the hold version of the budget period. This means you are about to process a new budget period - you then output a line with the hold vendor, hold budget period and the totals. You then zero out the totals, replace the hold budget period with the current budget period and continue. You will also check to see if/when the vendor changes, and do the same sort of thing.

FInally, when you reach the end of your dataset, you output the values for hold vendor hold budget period and your accumulated totals. No need to create an array of the data, since you will process it as you go.

mcriscolo 47 Posting Whiz in Training

On line 58 of your server.cpp, you are hanging on the "accept" call. That is, first time through, you accept the connection from your first client. It's running through your loop below, but there's no data, so it goes back to the top and hits the "accept" again, waiting for another connection. Only after the second client connects do you go through the loop, check the input and send the response back to the first client.

You will need to use a multiplexing function like "select" to check the readability of the sockets (including the "server" socket) so you don't hang on inbound connections. You will instead use the select function to test the sockets (you pass in an array of socket handles), and the return from the select call will indicate which handles are ready for reading (or accepting). This way, you can service data from connected clients without having to have new connections kick you off the accept call.

The GNU site has an example of a C/C++ socket server that uses select:

http://www.gnu.org/s/libc/manual/html_node/Server-Example.html#Server-Example

mcriscolo 47 Posting Whiz in Training

If it's a Windows Forms app, yes, you can use the Timer object and set the "Interval" property to the desired value, in milliseconds, then call the "Start()" method to start the timer. It will fire the "Tick" method when the interval is reached. From there, you can call any method you like.

If you want to do it all in code, you can use the System.Threading.Timer object. Plenty of examples on the web of how to use that facility, but generally:

Timer myTimer;

// myTimerCallBack - method to call
// someData - blob of data that will get passed to the callback (can be null)
// timeBeforeFirstExec (in milliseconds)  - time before the first time the timer fires
// period (in milliseconds) - recurring interval to fire the timer
myTimer = new Timer(myTimerCallback, someData, timeBeforeFirstExec, period);

public void myTimerCallback(Object obj)
{
    // obj is the "someData" from the call, above
    // Do timer stuff
}

Hope this helps.

mcriscolo 47 Posting Whiz in Training

One issue - the code:

string year = reader2[indexYear].ToString();

Is indexing the row using an integer value. For example, if "indexYear" is 2001, you will be trying to get the 2001st column of the row - of course, your row only has one column in it, hence the exception. Try this:

string year = reader2[indexYear.ToString()].ToString();

This will index the row by column name, rather than by number.

mcriscolo 47 Posting Whiz in Training

Have you hand-run your SQL statement to see what results it produces? It appears to me that the statement will only return a single column. However, in your statements after the "reader2.Read()", you are accessing multiple columns. If there's only one column in the result set, that code will definitely generate an IndexOutOfRange exception.

mcriscolo 47 Posting Whiz in Training

As always with this stuff, there are many ways to skin the proverbial cat. Using the timestamp method, you could even go as far as this: when you attempt to apply the update but find the record's been updated under you, re-read it into another buffer and compare the appropriate values, highlighting any differences and display to the user. Of course, that's a lot of elbow grease. More simply, you could just put a message out to the user saying "Another user has updated the record; please re-enter your changes" and re-display the form to the user with the new values from the newly-updated record.

mcriscolo 47 Posting Whiz in Training

One simple way is to use a DateTime or Timestamp column. When you update the row, check the timestamp to see if it matches the value you got when you pulled the record for editing. If it does not match, you know someone else updated the record while you were working on it.

mcriscolo 47 Posting Whiz in Training

Yep, that's pretty much it.

mcriscolo 47 Posting Whiz in Training

Well, first, is this program the client or the server? To really run it with two processes, you'll want one program to be the client, and another to be the server.

The server program should execute the Bind, Listen and Accept; while the client program executes the Connect method to connect to the server program. You appear to be doing both in the same program. You can actually do that...

In the server program, you need a local Socket object to perform the Bind and Listen. You also perform the Accept (this is where the server "comes alive" when a remote client connects to it), and the return value from the Accept is *another* socket - the socket to the remote client that just connected. The original socket can then go back to the Listen and wait for another client to connect.

When you have the programs separated, execute the server program first, then execute the client. If coded correctly, the client will connect up and you will be able to pass data back and forth.

Client:

m_IpEndPointForeign = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);

m_SocketForeign = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_SocketForeign.Connect(m_IpEndPointForeign);

m_Stream = new NetworkStream(m_SocketForeign);

// Read & Write operations
m_Stream.Write(...);  // Implementation left to you...

m_Stream.Close();
m_SocketForeign.Shutdown(SocketShutdown.Both);
m_SocketForeign.Close();

Server:

m_IpEndPointLocal = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);

m_SocketLocal = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

m_SocketLocal.Bind(m_IpEndPointLocal);
m_SocketLocal.Listen(10);
Socket m_SocketClient = m_SocketLocal.Accept();

m_Stream = new NetworkStream(m_SocketClient);

// Read & Write operations
m_Stream.Read();   // Actual Read() implementation left to coder...

m_Stream.Close();
m_SocketClient.Shutdown(SocketShutdown.Both); …
mcriscolo 47 Posting Whiz in Training

In your case, you haven't done anything with the IPEndPoint instance, so it depends.

If you want to connect to a remote client (the rest of your code appears as such), you need to issue the "Connect" call from the socket, using the IPEndPoint instance:

m_socket.Connect(m_IpEndPoint);

right after line 3 in your post (of course, you will also put this into a try/catch block in case of exceptions). This will connect your program to the end point described by host IP "127.0.0.71", on port "5000" (which answers your question - in this case, it's a foreign - or remote - address).

Now, the IPEndPoint can refer to a local address and port, if you were to do something like this, after line 3 in your code:

m_socket.Bind(m_IpEndPoint);
m_socket.Listen(10);
Socket m_client = m_socket.Accept();

assuming your machine's IP address is "127.0.0.71", this code would set up a listen on port 5000 so other programs could establish a connection to this process (again, you will enclose this code in a try/catch block to grab any exceptions). You would have to change the rest of your code to use "m_client", as this will be the object pointing to the socket a remote client would actually be "attached" to, for you to perform your reads/writes.

mcriscolo 47 Posting Whiz in Training

You then use:

printf("%4.3f", myFloatVar);

But note that if the value in "myFloatVar" has 2 digits left of the decimal, you'll get those two, along with the 3 past the decimal.

mcriscolo 47 Posting Whiz in Training

Use the proper format specifier in a printf statement:

printf("%.4f", myFloatVar);

This will display 4 positions past the decimal. See printf doc for more details.

mcriscolo 47 Posting Whiz in Training

A couple of things: first, you are mixing your class definition and method implementations together. You need to separate these into a header file for the class definition, and a code file for the method implementations. A short example (using your "booking" class):

New booking.h file:

#include <string>
using namespace std;
class booking
{
public:
booking(); /* constructor */
float calTicket(int numpass, string ctype);
};

New booking.cpp file:

#include "booking.h"

float booking::calTicket(int numpass, string ctype)
{
// Stuff the method is supposed to do...
}

Once you have that all separated, you should be a lot better off (code will be much more readable, too). Also, you don't need the "Friend" declarations. In your code, you just need to include the proper header, then just declare an instance of the class you want to use.

mcriscolo 47 Posting Whiz in Training

I take it that when you say "publish", you are using the publish command from the "Build" menu... if that's the case, then yes, when you get the output package from the Publish process, and then install it, it does install it into a subfolder of <SYSTEMDRIVE>\Documents and Settings\User\Local Settings\Apps\2.0. That is the folder you are seeing when you get the value from the "Application.StartupPath" property.

If you just copy your EXE (and any required supporting files) from your "Debug" (or "Release") folder to another location on your machine, the "Application.StartupPath" property will show you the correct location.

mcriscolo 47 Posting Whiz in Training

I'm not sure what you're after. You can load XML in from a file stream. You can put XML into a string. You can read XML into a string from a file stream. Perhaps some more detail about what you're trying to accomplish will help us in guiding you to a solution.

mcriscolo 47 Posting Whiz in Training

To answer the question about adding the ".cpp.o" rule: When I ran your makefile as is, I was seeing the compilation of the .cpp files (trying to make the output .o files) working, but it was not picking up the $(COMPILERFLAGS) variable. That is, this rule in your makefile:

$(BINARY): $(OBJS)
        $(CPPCOMPILER) $(COMPILERFLAGS) $(INCLUDES) -o $(BINARY)

when compiling the .cpp sources, was producing this output:

g++    -c -o /root/workspace/source/Main.o /root/workspace/source/Main.cpp

Where is the "-W -Wall"? Where is the "include" directive? It was not in the output of the command make was executing. This is why you were getting the build errors - it didn't know where to find the header files. That's because make was executing a default rule for the .cpp files, and not using the directives in the rule for building the executable. Once I added the ".cpp.o" rule, everything built - almost. The .cpp built and made the correct .o files, but when it was time to make the executable, I got this output:

g++ -W -Wall -c -I/root/workspace/makedemo/header -o output /root/workspace/source/Main.o /root/workspace/source/TestFile.o

That's because I had to put a "-c" into the COMPILERFLAGS variable, and now that it's trying to build the executable, the "-c" is trying to output object code rather than perform the link. This required the removal of the $(COMPILERFLAGS) variable from the rule that was building the executable.

Some of the macros for make: "$<" is the name of the file that caused the rule to be executed, …

mcriscolo 47 Posting Whiz in Training

In my sample, I put the loading of "about:blank" in Form_Load() to give the control time to navigate (and more important), initialize the "Body" member of the WebControl. If you put the "webcontrol1.Navigate" in the same routine that you try to load the control with your content, you will hang (I was seeing the same thing). Another sample I saw on the Internet (it was in VB.NET, though), was performing "DoEvents" to yield control back to the main loop to allow the webcontrol to intialize. I tried the same thing with a Thread.Sleep(200) call, but it didn't help.

All I can say is try to separate the "about:blank" call into a separate routine (perhaps even the Form's constructor) to give it time to load and initialize the "Body" element, so in a later routine, you can supply your content to the control and be OK.

mcriscolo 47 Posting Whiz in Training

You can use the WebBroswer control to display text. Drag a WebBrowser control onto your form. Put this in your Form_Load():

webBrowser1.Navigate("about:blank");

Then, use this code to fill it:

bool bError = true;
while (bError)
{
    try
    {
        webBrowser1.Document.Body.InnerHtml = "<HTML><BODY><H1>Hi!</H1</BODY></HTML>";
        bError = false;
    }
    catch (Exception exp)
    {
        ;
    }
}

The navigate to "about:blank" needs some time to complete; the loop and try..catch will help if the navigation is not complete. If you try too soon to put text into the control, you may get a NullReferenceException, since the "Body" member will still be NULL.

Hope this helps!

mcriscolo 47 Posting Whiz in Training

Try this makefile:

TOP_DIR = /root/workspace
S_DIR = $(TOP_DIR)/source
H_DIR = $(TOP_DIR)/makedemo/header

HEADERS = $(shell  ls $(H_DIR)/*.H)
SOURCES = $(shell ls $(S_DIR)/*.cpp)

COMPILERFLAGS = -W -Wall -c
DEBUGFLAGS = -g
CPPCOMPILER = g++

INCLUDES = -I$(H_DIR)

OBJS = $(SOURCES:.cpp=.o)

BINARY = output

all:    $(BINARY)

$(BINARY):      $(OBJS)
        $(CPPCOMPILER) -o $(BINARY) $(OBJS)

.cpp.o: $(SOURCES) $(HEADERS)
        cd $(S_DIR); $(CPPCOMPILER) $(COMPILERFLAGS) $(INCLUDES) $<

depend:
        makedepend $(INCLUDES) -f- -- $(SOURCES) > .depend_file
clean:
        rm -rf $(S_DIR)/*.o .depend_file $(BINARY) *~

#DO NOT DELETE

Your original makefile was not pointing to the proper include file, so it was not picking up your headers. That was the source of your errors. Here, I've suggested some changes that make the file somewhat cleaner (at least to me). See if they work for you.

I made the changes to the top, by adding some variables for the directories, since I'd have to go to them (for example, in the "clean" rule).

The other major addition is the ".cpp.o" rule to build the objects prior to linking the executable. I found that the one rule in the original Makefile was not picking up the stuff in COMPILERFLAGS, so I knew it was hitting a default rule for the .cpp items.

The *.o files will, by default, be dropped in the current folder where make is being run (in your example, /root/workspace/makedemo), but then the variables for the object files that have the paths pre-pended would fail during the link step. I fixed that by performing a "cd …

mcriscolo 47 Posting Whiz in Training

I'd do a separate array.

mcriscolo 47 Posting Whiz in Training

Well, checking your boxes for user input will be a chore. Having the controls in an array would help with that.

mcriscolo 47 Posting Whiz in Training

:icon_eek: There's a lot of stuff flying around here.

OK, here's some code to get the grid of TextBoxes displayed, and a button that shows some basic interaction:

Put this at the top of your form's class:

TextBox[,] tb = null;

Put this into your Form_Load():

tb = new TextBox[9,9];

for (int i = 0; i < 9; i++)
{
    for (int j = 0; j < 9; j++)
    {
        tb[i, j] = new TextBox();
        tb[i, j].Visible = true;
        // These numbers are just a bit wider and taller than the text
        // box we're adding.  Feel free to goof with them to get the
        // look you want
        tb[i, j].Location = new Point(i * 41, j * 35) ;
        tb[i, j].Width = 40;
        this.Controls.Add(tb[i, j]);
    }
}

If you don't have a Form_Load(), you can get one by double-clicking on any blank area inside the form on the designer.

Drag a button onto the form, all the way to the right. Double click it and put this code into the button1_click() method (or whatever it's named):

for (int i = 0; i < 9; i++)
{
    for (int j = 0; j < 9; j++)
    {
        tb[i, j].Text = ((i * 9) + j).ToString();
    }
}

Some points:

The declaration of the array of text boxes must be global - you'll be accessing them later, so you can't declare it inside a method (like Form1()).

The button shows how you can …

mcriscolo 47 Posting Whiz in Training

Please post your updated makefile and I'll take a look.

mcriscolo 47 Posting Whiz in Training

Your shell commands are off. Try this:

HEADERS = $(shell ls /root/workspace/makedemo/header/*.h)
SOURCES = $(shell ls /root/workspace/source/*.cpp)
mcriscolo 47 Posting Whiz in Training

You are technically already running the program, so you really only need to check to see if the user doesn't want to run it:

if (answer == 'n')
    return 0;

Otherwise, execution will continue.

mcriscolo 47 Posting Whiz in Training

Some things I'm reading seem to indicate that you cannot use the IDE to create a DataSet that is hooked to a remote SQL Server database. I don't happen to have VS 2008 Express, so I can't test that (the previous example I gave was with the full version of VS2008).

However, in code you should be able to get to the database. Try this code in a test project:
At the top of the module, put:

using System.Data.SqlClient;

In a button_click routine somewhere, put this code:

SqlConnection oConn = new SqlConnection("Server=DBServer;Database=DB;user id=youruser;password=yourpw");
            SqlDataReader myReader = null;
            int count = 0;
            try
            {
                oConn.Open();
            }
            catch (SqlException ex1)
            {
                MessageBox.Show(ex1.Message, "Exception: Open");
                return;
            }
 
            SqlCommand cmd = new SqlCommand("Select * from tb_table", oConn);
 
            try
            {
                myReader = cmd.ExecuteReader();
            }
            catch (SqlException ex2)
            {
                MessageBox.Show(ex2.Message, "Exception: Execute");
                return;
            }
 
            while (myReader.Read())
            {
                count++;
            }
            myReader.Close();
            oConn.Close();
 
            MessageBox.Show("Got " + count.ToString() + " record(s)", "Success!");

Of course, replace the various components (DBServer, DB, youruser, yourpw and tb_table) with values that work in your environment. The success case should be a message box reporting the number of records in the table.

mcriscolo 47 Posting Whiz in Training

You can add an event handler for the button by using the following syntax:

this.buttonDec.Click += new System.EventHandler(this.buttonDec_Click);

Then, define your handler function somewhere in your form code:

private void buttonDec_Click(object sender, EventArgs e)
{
...
}

However, since you are not wanting (I think!) to control the push button via arrays, you can safely drop a button on the form using the Designer and you should be OK, avoiding all the above stuff. You would only need an array of buttons if you plan on having a button for each set of TextBoxes.

mcriscolo 47 Posting Whiz in Training

Actually, you can use control arrays, but you will have to build the TextBoxes (or any other controls) manually, rather than using the designer (unless someone out there knows a way!).

Here's some code that will construct 6 TextBoxes, put them on the form and make sure they're visible:

At the top of your form class:

TextBox[] tb;

In your Form_Load():

tb = new TextBox[6];        
    for (int i = 0; i < 6; i++)
    {
         tb[i] = new TextBox();
         tb[i].Visible = true;
         tb[i].Top = 100 + (i * 50);
         tb[i].Width = 200;
         this.Controls.Add(tb[i]);
    }

You can now interact with the TextBoxes in the array. This should get you started. Good luck!

mcriscolo 47 Posting Whiz in Training

If you don't mind including <arpa/inet.h>, you can use the htonl() function:

int newval = htonl(origval);

The "h" on the front is for "host" and the "n" is for network, "l" on the end for "long" (there is also a version for 16-bit integers). Hence, "Host to network Long". Network format is big endian.

On platforms that are already big endian (like Solaris), it's defined as a NULL macro.

mcriscolo 47 Posting Whiz in Training

If you'll notice, you specify "this.Controls". Those controls contain all of the controls on your form, not just the TextBox-es. You need to check the type of each control as you iterate over it, to make sure it's a TextBox.

Something like:

foreach (Control c in this.Controls)
{
    if (c.GetType().ToString() == "System.Windows.Forms.TextBox")
    {
        ((TextBox)c).Text = "";
    }
}
mcriscolo 47 Posting Whiz in Training

Just asking, but did you stop and restart Visual Studio after you did the install?

mcriscolo 47 Posting Whiz in Training

OK, perhaps you don't have the SQL Native Client installed. You can check the Control Panel to see if it is installed (once you open Control Panel, go to "Add or Remove Programs" or "Programs and Features" if you're in Vista).

If it is not, you can download it from here.

Once you have it installed, you should some additional choices for setting up your connection.

mcriscolo 47 Posting Whiz in Training

You can select "SQL Server" to connect to a local or remote SQL Server instance. From the "Data" menu, select "Add New Data Source", select "Database", press "Next", then press "New Connection". In the "Choose Data Source" box that comes up, select "SQL Server". Once you do that, the combobox below will fill with 2 choices - the .NET provider for SQL Server (default) or the .NET provider for OLD DB. Select the .NET Provider for SQL Server, then press "Continue". Now, you can select the database you want to use, and it will build the DataSet and place it into your project.

mcriscolo 47 Posting Whiz in Training

If you mean that you want to manipulate an Excel workbook from a C# Windows app, then perhaps this link will help.

mcriscolo 47 Posting Whiz in Training

Ah, but you can! Using the Controls.Find() method, you can search for an instance of a control on a form. So, if you name your text boxes "txt001", "txt002", etc., you can run code like this:

Controls[] x = this.Controls.Find(sControlName, true);

to get an array of controls that match the string in "sControlName". Assuming only one control matches your string, code like this:

TextBox z = (TextBox)x[0];

will give you a variable, "z", that can be handled like any TextBox.

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

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.