Steve
Steve

Reputation: 1985

sprintf() and WriteFile() affecting string Buffer

I have a very weird problem which I cannot seem to figure out. Unfortunately, I'm not even sure how to describe it without describing my entire application. What I am trying to do is:

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 right tag code sent back out the serial port. But there are two lines that I've added as debug statements which when I tried to remove them, they cause my program to stop working.

The lines are the two lines at the very bottom:

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

If I try to remove them, "tagBuffer" will only store the last character as oppose being a buffer. Same thing with the next line, WriteFile().

I thought sprintf and WriteFile are I/O functions and would have no effect on variables. I'm 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);

    }
}

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

Without them, I figured out that tagBuffer and buf only stores the most recent character at any one time.

Any help at all will be greatly appreciated. Thanks.

Upvotes: 1

Views: 1880

Answers (4)

ChrisN
ChrisN

Reputation: 16943

In my opinion, the real problem here is that you're trying to read and write the serial port from a single thread, and this is making the code more complex than it needs to be. I suggest that you read the following articles and reconsider your design:

In a multithreaded implementation, whenever the reader thread reads a message from the serial port you would then post it to your application's main thread. The main thread would then parse the message and query the database, and then queue an appropriate response to the writer thread.

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

I hope this helps!

Upvotes: 0

user31394
user31394

Reputation:

The first thing I'd say is a piece of general advice: bugs aren't always where you think they are. If you've got something going on that doesn't seem to make sense, it often means that your assumptions somewhere else are wrong.

Here, it does seem very unlikely that an sprintf() and a WriteFile() will change the state of the "buf" array variable. However, those two lines of test code do write to "hSerial", while your main loop also reads from "hSerial". That sounds like a recipie for changing the behaviour of your program.

Suggestion: Change your lines of debugging output to store the output somewhere else: to a dialog box, or to a log file, or similar. Debugging output should generally not go to files used in the core logic, as that's too likely to change how the core logic behaves.

Upvotes: 1

1800 INFORMATION
1800 INFORMATION

Reputation: 135315

It seems unlikely that those two lines would have that effect on a correct program - maybe you haven't allocated sufficient space in buf for the whole length of the string in tagBuffer? This might cause a buffer overrun that is disguising the real problem?

Upvotes: 1

Martin Beckett
Martin Beckett

Reputation: 96119

Where are you allocating tagbuffer, how large is it?
It's possible that you are overwriting 'buf' because you are writing past the end of tagbuffer.

Upvotes: 1

Related Questions