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.
source to share
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.
source to share
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:
- Serial I / O port from Joseph Newcomer website.
- Serial communication in Win32 from MSDN.
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!
source to share