2008-11-09 57 views
1

我有一个很奇怪的问题,我似乎无法弄清楚。不幸的是,我甚至不确定如何描述它,而没有描述我的整个应用程序。我想要做的是:sprintf()和WriteFile()影响字符串缓冲区

 
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 

我的大部分代码都实现了,我可以从串口发回正确的标签代码。但是我添加了两行作为调试语句,当我试图删除它们时,它们导致我的程序停止工作。

的线是在最下方的两行:

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

如果我试图删除它们,“tagBuffer”将只存储的最后一个字符为反对是一个缓冲。与下一行WriteFile()相同。

我认为sprintf和WriteFile是I/O函数,并且对变量没有影响。 我卡住了,我需要帮助来解决这个问题。

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

    } 
} 

有了这两条线,我的输出是这样的: 小号SH她SHEL货架shelf0 shelf00的bookcode shelf0001

如果没有他们,我想通了,tagBuffer和BUF只保存最近的字符在任何时候。

任何帮助都将不胜感激。谢谢。

+0

你在哪里以及如何定义tagBuffer? – 2008-11-09 07:59:57

+0

char tagBuffer [8]; //保存标记ID int i = 0; // indexBuffer – Steve 2008-11-09 08:04:56

回答

1

你在哪里分配tagbuffer,它有多大?
您可能正在覆盖'buf',因为您正在写入tagbuffer的末尾。

1

这两行似乎不太可能对正确的程序产生影响 - 可能您没有在tagBuffer中为buf字符串的整个长度分配足够的空间?这可能会导致缓冲区溢出,从而掩盖真正的问题?

1

我要说的第一件事就是一般性建议:错误并不总是你认为它们的地方。如果你发生了某些似乎没有道理的事情,通常意味着你在其他地方的假设是错误的。

在这里,sprintf()和WriteFile()会改变“buf”数组变量的状态似乎不太可能。但是,这两行测试代码确实写入“hSerial”,而您的主循环也从“hSerial”中读取。这听起来像是改变程序行为的收件人。

建议:更改您的调试输出行以将输出存储在其他位置:到对话框或日志文件或类似位置。调试输出通常不应用于核心逻辑中使用的文件,因为这很可能会改变核心逻辑的行为方式。

0

在我看来,真正的问题在于,你试图从单个线程读写串行端口,这使得代码比需要的更复杂。我建议你阅读以下文章并重新考虑你的设计:

在多线程实现中,只要读写器线程从串口读取消息,就会将其发布到应用程序的主线程。主线程然后解析消息并查询数据库,然后将适当的响应排列到写入器线程。像Newcomer解释的那样,这听起来可能比您当前的设计更为复杂,但实际上并不是这样。

我希望这有助于!