snprintf格式化字符串遇到std::string包含\0的問題


在發送帶有簽名數據時,使用snprintf格式化數據,發現簽名數據有時候有漏掉的情況

如下:

char AuthBidirection[320] = { '\0' };
snprintf(AuthBidirection, 320, "Bidirection algorithm=\"%s\",random1=\"%s\",random2=\"%s\",deviceid=\"%s\",serverid=\"%s\",sign1=\"%s\"
", strAlgorithm.c_str(), m_strRandom1.c_str(), strRandom2.c_str(), m_strGbID.c_str(), m_strGbServerID.c_str(), sign1.c_str());

改為:

char AuthBidirection[320] = { '\0' };
snprintf(AuthBidirection, 320, "Bidirection algorithm=\"%s\",random1=\"%s\",random2=\"%s\",deviceid=\"%s\",serverid=\"%s\",sign1=",
strAlgorithm.c_str(), m_strRandom1.c_str(), strRandom2.c_str(), m_strGbID.c_str(), m_strGbServerID.c_str());
//added ”“ to sign1
string strTempSign1 = "\"" + sign1;
strTempSign1.push_back('\"');
memcpy(AuthBidirection + strlen(AuthBidirection), strTempSign1.c_str(), strTempSign1.size());

使用memcpy替代

原因:經過簽名后的數據,放入類型為std::string的sign的數據有可能會遇到\0的字符,

然后,然后,然后。。。,sign1.c_str()返回的是一個字符數組的起始地址,往sprintf里面放的時候自然到\0就結束了,后面的數據就被直接漏掉了。。。。。。

 

單獨拎出來驗證一下: 

    char *buf = new char[5];
    memcpy(buf,(void *)"abc\0d", 5);
    string strSig;
    strSig.assign(buf, 5);
    int len = strSig.size();
    std::cout << strSig.size() << std::endl; //5
    std::cout << strSig[4] << std::endl; //d     char AuthBidirection[320] = { '\0' };
    snprintf(AuthBidirection, 320, "strSig=%s", strSig.c_str());
    std::cout << AuthBidirection[11] << std::endl; //打印空字符,因為沒有放進去,后面都是空的     char AuthBidirection1[320] = { '\0' };
    snprintf(AuthBidirection1, 320, "strSig=%s", "");
    memcpy(AuthBidirection1 + strlen(AuthBidirection1), strSig.c_str(),len);
    std::cout << AuthBidirection1[11] << std::endl; //d

輸出:

5
d

d

最后的d一個放進去了,一個沒有

 

因此,在使用string進行數據處理的時候,需要特別注意size大小,特別是涉及網絡發包時,要格外注意使用strSig.c_str()來處理,strSig.c_str()僅僅是一個起始地址,

因此碰到字符串處理函數如snprintf等等,都是以\0為結束標記來處理的,所以需要謹慎再三。  此前也有遇到過類似,因此才能迅速發現問題,記錄一下。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM