Take the 2-minute tour ×

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,
            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))

    // Wait 5 seconds for serial input
    if (!(HasOverlappedIoCompleted(&ovRead)))

    // Check if serial input has arrived
    if (GetOverlappedResult(hSerial,&ovRead,
        // Wait for the write

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

        //load tagBuffer with byte stream
        tagBuffer[i] = szRxChar;
        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" )
           else if ( str == "shelf" )
           else //this else doesn't work


        // 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


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.

share|improve this question
Where and how are you defining tagBuffer? –  Jason Coco Nov 9 '08 at 7:59
char tagBuffer[8]; //holds the tag id int i=0; //index for tagBuffer –  Steve Nov 9 '08 at 8:04
well if your output is correct then you're definitely overrunning tagBuffer... if you change it to tagBuffer[32] (or some other large number) and comment out those lines, does it work as expected? –  Jason Coco Nov 9 '08 at 8:08
With 32, I get tagBuffer = (the most recent character) while buf is garbage according to stdout –  Steve Nov 9 '08 at 8:14

4 Answers 4

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.

share|improve this answer

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?

share|improve this answer

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.

share|improve this answer
Thanks for the advice. I removed those lines and output them to stdout This is what I got: buf is ! tagBuffer is s! buf is ! tagBuffer is h! buf is ! tagBuffer is e! buf is ! tagBuffer is l! buf is ! tagBuffer is f! buf is ! tagBuffer is 0! buf is ! tagBuffer is 0! buf is ! tagBuffer is 1! –  Steve Nov 9 '08 at 8:12
It seems like buf is not storing anything –  Steve Nov 9 '08 at 8:16
I'd also suggest adding logging to stdout in all the cases where your indexing variable 'i' gets re-set to zero. Is one of those cases getting triggered for every character read? –  DavidK Nov 9 '08 at 8:31

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!

share|improve this answer

Your Answer


