Sprintf () and WriteFile () affecting the string buffer

I have a very strange problem that I cannot figure out. Unfortunately, I don't even know how to describe this without describing my application. I am trying to do this:

1) read a byte from the serial port
2) store each char into tagBuffer as they are read
3) run a query using tagBuffer to see what type of tag it is (book or shelf tag)
4) depending on the type of tag, output a series of bytes corresponding to the type of tag

Most of my code is implemented and I can get the correct tag code sent back over the serial port. But there are two lines that I added as debug statements, which when I tried to remove them, causes my program to stop working.

Lines are two lines at the very bottom:

    sprintf(buf,"%s!\n", tagBuffer);
    WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);

      

code>

If I try to delete them, "tagBuffer" only stores the last character, since it is a buffer. Same with the next line, WriteFile ().

I thought sprintf and WriteFile were I / O functions and would not affect variables. I am stuck and I need help to fix this.



//keep polling as long as stop character '-' is not read
while(szRxChar != '-')
{
    // Check if a read is outstanding
    if (HasOverlappedIoCompleted(&ovRead))
    {
        // Issue a serial port read
        if (!ReadFile(hSerial,&szRxChar,1,
                &dwBytesRead,&ovRead))
        {
            DWORD dwErr = GetLastError();
            if (dwErr!=ERROR_IO_PENDING)
                return dwErr;
        }
    }

    // resets tagBuffer in case tagBuffer is out of sync
    time_t t_time = time(0);
    char buf[50];
    if (HasOverlappedIoCompleted(&ovWrite))
    {
        i=0;                                       
    }

    // Wait 5 seconds for serial input
    if (!(HasOverlappedIoCompleted(&ovRead)))
    {
        WaitForSingleObject(hReadEvent,RESET_TIME);
    }

    // Check if serial input has arrived
    if (GetOverlappedResult(hSerial,&ovRead,
            &dwBytesRead,FALSE))
    {
        // Wait for the write
        GetOverlappedResult(hSerial,&ovWrite,
            &dwBytesWritten,TRUE);

        if( strlen(tagBuffer) >= PACKET_LENGTH )
        {
            i = 0;
        }

        //load tagBuffer with byte stream
        tagBuffer[i] = szRxChar;
        i++;
        tagBuffer[i] = 0; //char arrays are \0 terminated

        //run query with tagBuffer  
        sprintf(query,"select type from rfid where rfidnum=\"");
        strcat(query, tagBuffer);
        strcat(query, "\"");
        mysql_real_query(&mysql,query,(unsigned int)strlen(query));

        //process result and send back to handheld
        res = mysql_use_result(&mysql);
        while(row = mysql_fetch_row(res))
        {
           printf("result of query is %s\n",row[0]);

           string str = "";
           str = string(row[0]);

           if( str == "book" )
           {
               WriteFile(hSerial,BOOK_INDICATOR,strlen(BOOK_INDICATOR),
                &dwBytesWritten,&ovWrite);
           }
           else if ( str == "shelf" )
           {
               WriteFile(hSerial,SHELF_INDICATOR,strlen(SHELF_INDICATOR),
                &dwBytesWritten,&ovWrite);
           }
           else //this else doesn't work
           {
               WriteFile(hSerial,NOK,strlen(NOK),
                &dwBytesWritten,&ovWrite);
           }
        }


        mysql_free_result(res);

        // Display a response to input
        //printf("query is %s!\n", query);
        //printf("strlen(tagBuffer) is %d!\n", strlen(tagBuffer));

        //without these, tagBuffer only holds the last character
        sprintf(buf,"%s!\n", tagBuffer);
        WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);

    }
}

      

code>

With these two lines, my output looks like this: s sh she shelf shelf shelf0 shelf BOOKCODE shelf0001

Without them, I realized that tagBuffer and buf only store the last character at any given time.

Any help whatsoever would be appreciated. Thank.

+1


source to share


4 answers


Where do you place the tagbuffer, how big is it?
Perhaps you are overwriting "buf" because you are writing the end of the end of the tagbuffer.



+1


source


It seems unlikely that these two lines would have this effect on a correct program - perhaps you haven't allocated enough space in buf

for the entire length of the line in tagBuffer

? Could this cause a buffer overflow that masks the real problem?



+1


source


The first thing I would say is general advice: mistakes are not always where you think. If you have something going on it doesn't seem to make sense, it often means that your assumptions elsewhere are wrong.

Here it is very unlikely that sprintf () and WriteFile () will change the state of the "buf" array variable. However, these two lines of test code are being written to "hSerial", while your main loop is also reading from "hSerial". It looks like a recipe for changing the behavior of your program.

Sentence. Change your debug output lines to store the output somewhere else: in a dialog box or in a log file or similar. Debug output should usually not refer to files used in the main logic, as this can change the behavior of the main logic.

+1


source


In my opinion, the real problem is that you are trying to read and write a serial port from the same thread and this makes the code more complicated than it needs to be. I suggest you read the following articles and revisit your design:

In a multi-threaded implementation, whenever a read thread reads a message from the serial port, you then send it to the main thread of the application. The main thread then processed the message and queried the database, and then posted the appropriate response to the write thread.

This may sound more complicated than your current design, but it really isn't, as Newcomer explains.

Hope this helps!

0


source







All Articles