RonalBertogi 46 Junior Poster in Training

Review the instructions to your assignment. Sometimes are error is not the coding itself but the failure to follow instructions.

Like this:

...data in the file. Your input and output file names will be supplied to your program on the command line, which you will access using argc and argv[]

...but in line 23 you asked the user to enter the input file.

Of course, there are still other errors in your code (like line 20(?)) but review--and understand well--your instruction and rewrite your code and try to compile and run it so that you yourself can see the problem. It is the compiler's task to inform us the errors (except of course logical errors) and it is our task to fix them. If your compiler tells about errors, try to understand them first and fix them yourself until you prove to yourself you need the others' help. That way, I suppose, you will learn programming systematically.

RonalBertogi 46 Junior Poster in Training

First of all, I did not see any variable declared with an identifier To and From. But I suppose the main error in this class is your declaration if these variables: m_To, m_From and m_Msg. They are all pointers. And the fact that they are pointers, you should not call the delete operator on them unless you have initialized them with the new operator.

Let's look at the mutators of these variables. Since they are all in the same code pattern, we will just look particularly at the SetMessage function specifically on line 43.

On Line 43 you assigned the value of the actual parameter called value to m_Msg data of your class using the assignment operator--WITHOUT allocating an appropriate amount of memory for m_Msg to accomodate the length of the value. In some few (and rare) cases this can be ok. But the problem is if the memory pointed to in the formal parameter value is a non-static memory where it will automatically be freed when the function where the SetMessage was called from exits.

Example:

void InitializeChat(CMsgPacket * pMsgPacket)
{
    char msg[] = "A message"; // This is a temp variable that will be
                              // destroyed when the function exits.
    pMsgPacket.SetMessage(msg);
}

void main()
{
    CMsgPacket msg;
    InitializeChat(&msg);
}

pMsgPacket.SetMessage() was called with a temporary variable as its argument that will be assigned to the m_Msg data of the CMsgPacket class. When InitializeChat exits, the value assigned to the m_Msg will no longer be valid.

I …

mike_2000_17 commented: Nice! +14
RonalBertogi 46 Junior Poster in Training

You just declared the structure of the class, its ctor and dtor and some data members. Does your project files include a source file that will define the class?

RonalBertogi 46 Junior Poster in Training

...and for a cleaner coding you can cause the switch statement:

After lines #7 & #8 of Milton Neal's post:

switch( sign )
{
    case '+':
        statements;
        break;
    case '-':
        statements;
        break;
    case '*':
        statements;
        break;
    case '/':
        statements;
        break;
    default:
        cout<<"Invalid sign "<<"("<<sign<<") used.";
}

Replace statements with your actual statements.

ddanbe commented: The best solution +14
RonalBertogi 46 Junior Poster in Training

if you just want to check if your process is still alive or dead using the process id (pid) you have, calling the OpenProcess API would suffice.

RonalBertogi 46 Junior Poster in Training

But, in continuation to deceptikon's reply, if you just want to be able to call ShellExecute while enabling you to pass your sProgramName variable as an argument, you can use its ANSI version without much hassles, e. g. ShellExecuteA(NULL, NULL, &sProgramName[0], NULL, NULL, SW_SHOW);

CodeAngry commented: this is the solution for your problem +0
RonalBertogi 46 Junior Poster in Training

I meant in example #2 "for( ;szHex;szHex++ )" which I did actually type. But I lost my asterisk symbols.

RonalBertogi 46 Junior Poster in Training

Well, I think there's no way to directly convert hex to octal because a hex value needs to be parsed first to get its value in real numbers (decimal). But the process is always the same: to convert decimal to another notation (hex, octal) you divide the number with your base (radix), putting the remainder right to left, until you get a zero quotient. Converting from other notation to decimal, start from 0, multiply it with 10 and parse and add the value of that notation starting from the left.

Here I'll show you some example: Note that numerical notations other than decimal can only be stored in strings (well, it's only my assumption and someone may correct me if I'm wrong).

  1. Converting decimal to dexadecimal

    const char * dectohex(long num)
    {
        static char szout[11];
        long c;
        int pos = 10;
        memset(szout, '0', 10);
        while( num )
        {
            c = num % 16;
            if( c<=9 )
                szout[pos--] = '0' + c;
            else
                szout[pos--] = 'A' + c;
            num /= 16;
        }
        szout[0] = '0';
        szout[1] = 'x';
        return szout;
    }
    
  2. Converting hex to decimal

    long hextodec(const char * szHex)
    {
        long ret = 0;
        char h;
        for( ;*szHex;*szHex++ )
        {
            h = tolower(*szHex);
            if( '0'<=h && h<='9' )
                ret = ret * 10 + (h - '0');
            else if( 'a'<=h && h<='f' )
                ret = ret * 10 + (10 + h - 'a');
            else
                break;
        }
        return ret;
    }
    
RonalBertogi 46 Junior Poster in Training

Let's examine the code in your binarySearchTree::insert() function line by line:

treeNode *temp;
treeNode *add;

here you allocated memory for you local add variable and set its item property
to the value of x

add = new treeNode;
add->item=x;
temp=root;
if(temp==NULL)

this line here will be executed the first time insert() is called since root is
initialized to NULL in this class' constructor.

    root=add;

root->item now is equal to 1598

else{

This code block here will then be executed in the succeeding calls to the function beccause root is no longer NULL, reiterating until temp becomes NULL. But no matter how many times will this block loop, this does actually nothing to insert the new value which is 160 in your second call.

    while(temp!=NULL){
        if(temp->item>=add->item)
            temp=temp->left;////////////It's here that I encounter the runtime error..why is this?
        else
            temp=temp->right;
    }

Even this line here would not affect your root member. Doing nothing significant.

    temp=add;
}

Hope this could help you.

RonalBertogi 46 Junior Poster in Training

Oh, Bile, I guess it's in Program Files\Microsoft Visual Studio\VB98\Template. In that folder there are different subfolders that for each respective type of template: forms, classes, etc. etc.

RonalBertogi 46 Junior Poster in Training

Create your form with all the menus you need, save it (with the name that will help you identify it's contents) and copy it to the forms templates folder of visual basic. About this folder, :( I can no longer remember where exactly it is. Haven't been using vb6 for quite a long time now.

RonalBertogi 46 Junior Poster in Training

What kind of error are you receiving, run-time or compile time? May I know the IDE you are using and its version?

RonalBertogi 46 Junior Poster in Training

@Fearless Hornet,

I tried your code in my own project and it worked without errors. Of course, I did export your functions from my dll and called them in my exe.

However, did you try to execute your code step by step? I suggest you do this if you haven't yet and try to temporarily comment out the following lines:

for (auto s : vowels)
{
    OutputLog(s.c_str());
}
std::cout << std::endl;
for (auto i : novowels)
{
    OutputLog(i.c_str());
}
RonalBertogi 46 Junior Poster in Training

You are exporting your functions the wrong way!!!

Based on your code...

The code used to call the function is:
std::vector<std::string> vowels, novowels;
std::string info("test snippet of data");
std::string tokens("aeiou ");
vowels = Editor::StringHandler::Split(info);
novowels = Editor::StringHandler::Split(info, tokens);

...the functions Editor::StringHandler::Split() and its overload is expected to return a value which type is std::vector<std::string>. You defined these functions correctly but you exported them with type void.

To correctly export these functions use this syntax: std::vector<std::string> DATAEDITING_API Split(...)

And...just a humble comment: I don't see any benefit in creating dll exports that are static members of a class. Why don't just export these functions by themselves without a class and/or namespace?

RonalBertogi 46 Junior Poster in Training

How did you export this function from your DLL?

RonalBertogi 46 Junior Poster in Training

Query = "DELETE FROM census WHERE txtEnterID ='" & strId & "'"
Are you sure txtEnterID field exists in your census table? Query filter names must be existing fields in the database's tables. If it don't exist you will get this error. And more thing, data must match with the data type of that field. If it's a string then you would pass string data in single quotes. Numbers don't have and MUST not be enclosed in quotes.

To be sure, open your database and look at your table, in this case the census. Select the field/(s) that would contain the unique data and use them as your filters in your delete query.

RonalBertogi 46 Junior Poster in Training

BTW, where is your OutBuffer? How was it initialized and, if ever, modified later? This could be the culprit.
string subString_is = getcmd.substr(0,3);//Extract PM00 from txt Are you sure you got 'PM00' when you get a subtring which length is only 3?
InBuffer[14] = 0x0A ??? This will overwrite the 15th character of your InBuffer. Is this intended?
memcpy(&InBuffer[15],"\0",1) This is not necessary. InBuffer[15 would suffice. If you use strcpy, this line will not even be necessary.

-----------------------------------------

Hello, I did not want to make this a new post. I tried to edit my previous post but I didn't know how to update it, as in, I didn't find a way. :(

anukavi commented: got a temporary soln to it... thanks a lot for the post.. +0
RonalBertogi 46 Junior Poster in Training

Based on your code, you are expecting characters 'K' and 'L' that when met, you will copy two groups of character which lengths are 6 and 4, respectively. What if these conditions are not satisfied, do you have a handler to this?

One more thing, I suggest using strcpy than memcpy since the former automatically adds a terminating null character.

RonalBertogi 46 Junior Poster in Training

If you really have typed line 3 (in reference to nullptr's post) that way, it is sure to generate a compile-time error cannot convert parameter 1 from 'char' to 'void *'. But if you have typed it like line 2, I'm pretty sure you will get a 14.

RonalBertogi 46 Junior Poster in Training

@meLiel,

As what I've said in my previous post, you have to make sure that you have successfully established the connection to your database before doing any database operation (e. g. querying, udpating, deleteing, etc) thus the error.

Here is a simple procedure to do that:

Dim conDB As ADODB.Connection ' it is sometimes ideal to make this a global variable when
                              ' you will be just accessing a single database

In your startup procedure (either in Sub Main() or in your Form_Initialize() procedure) set this following code:

Set conDB = new ADODB.Connection
conDB.CursorLocation = adUseClient

'Be sure to handle errors properly in case they occur
On Error Goto abort_app
conDB.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<<Your_Database_Path>>;Persist Security Info=False"
Exit Sub

abort_app:
    MsgBox "Error opening database"
    Unload Me

NOTE: Make appropriate modification in the previous code. Such code was in the context of the Form_Initialize event of your Visual Basic form.

Now that you hvae already made the connection, you can do whatever you want to your database. Of course, it will still depend on the features provided by the provider.

Now, to delete a record, it's just as simple as

DELETE FROM <<tablename>> WHERE <<fieldFilter>>='discardable'

What makes sure that you won't delete the records you don't want to is the filter. You can add more filters to narrow the selection of records you want to delete like this:

DELETE FROM myTable WHERE record1='invalidrecord' AND record2=0 AND IsIncorrect Is True

AndreRet commented: Thanx +12
RonalBertogi 46 Junior Poster in Training

The code below assumes that you have already established your database connection. To delete a particular record the code is:

con.Execute "DELETE FROM <<tablename>> WHERE <<fieldFilter>>='discardable'"

NOTES:

  1. fieldFilter is the name of field in the table where you are to delete records.
  2. fieldFilter can take different systax. It can be a string like in this example where single-quotes are mandatory. If it's a number then the quotes is not needed. If your fieldFilter is a boolean, the syntax should be this: <<fieldFilter Is True>>. When you specify your actual tablename and fieldFilter name, omit these << and these >>.
RonalBertogi 46 Junior Poster in Training

The code below assumes that you have already established your database connection. To delete a particular record the code is:

con.Execute "DELETE FROM <<tablename>> WHERE <<fieldFilter>>='discardable'"

NOTES:

  1. fieldFilter is the name of field in the table where you are to delete records.
  2. fieldFilter can take different systax. It can be a string like in this example where single-quotes are mandatory. If it's a number then the quotes is not needed. If your fieldFilter is a boolean, the syntax should be this: <<fieldFilter Is True>>. When you specify your actual tablename and fieldFilter name, omit these << and these >>.