sprintf()和WriteFile()影响字符串Buffer

时间:2008-11-09 07:51:58

标签: printf 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);

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

    }
}

使用这两行,我的输出如下所示: s sh she shel shelf shelf0 shelf00 BOOKCODE shelf0001

没有它们,我发现tagBuffer和buf只能在任何时候存储最新的字符。

任何帮助都将非常感谢。感谢。

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

我要说的第一件事是一条一般建议:错误并不总是你认为的错误。如果你有一些事情似乎没有意义,那通常意味着你在其他地方做出的假设是错误的。

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

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

答案 3 :(得分:0)

在我看来,这里真正的问题是你试图从一个线程读取和编写串口,这使得代码变得比它需要的更复杂。我建议您阅读以下文章并重新考虑您的设计:

在多线程实现中,只要读者线程从串行端口读取消息,您就会将其发布到应用程序的主线程中。然后,主线程将解析消息并查询数据库,然后将相应的响应排入编写器线程。

这可能听起来比你当前的设计更复杂,但事实并非像Newcomer所解释的那样。

我希望这有帮助!