如何含有NULL(0x00)的字串 |
尚未結案
|
aplay
一般會員 發表:2 回覆:10 積分:7 註冊:2004-10-14 發送簡訊給我 |
各位大大,我想要以傳址呼叫傳回字串,可是我卻疑質無法完整的複製與傳送,不知道有什麼樣的方法可以解決這樣的問題?
bool Load::SetPackage(char *pcCommand,char *pcPackage){ char cTemp[30]=" "; char cBuffer[30]=""; long lLen=0; int iFlag =0; int iSize =0; long lChecksum = 0; long lTempVal = 0; string sTemp; try { lLen = strlen(pcCommand); sprintf(cTemp,"%s",pcCommand); iSize=strlen(cTemp); memmove(pcPackage,cTemp,sizeof(cTemp)); lLen = 5 strlen(pcPackage); cBuffer[iFlag ] = 0x01; cBuffer[iFlag ] = 0x00; ------>填入一個空字元 cBuffer[iFlag ] = lLen; cBuffer[iFlag ] = 0x30; cBuffer[iFlag ] = 0x30; sprintf(&cBuffer[iFlag],"%s",cTemp); iFlag =strlen(cTemp); cBuffer[iFlag ]=';'; //char ';' for (int i = 1;i |
smartboss
初階會員 發表:19 回覆:93 積分:42 註冊:2004-12-29 發送簡訊給我 |
引言: 各位大大,我想要以傳址呼叫傳回字串,可是我卻疑質無法完整的複製與傳送,不知道有什麼樣的方法可以解決這樣的問題?您好我想您遇到的問題應該不是 memcpy 出了問題,您的問題應該像下面這個例子這樣bool Load::SetPackage(char *pcCommand,char *pcPackage){ char cTemp[30]=" "; char cBuffer[30]=""; long lLen=0; int iFlag =0; int iSize =0; long lChecksum = 0; long lTempVal = 0; string sTemp; try { lLen = strlen(pcCommand); sprintf(cTemp,"%s",pcCommand); iSize=strlen(cTemp); memmove(pcPackage,cTemp,sizeof(cTemp)); lLen = 5 strlen(pcPackage); cBuffer[iFlag ] = 0x01; cBuffer[iFlag ] = 0x00; ------>填入一個空字元 cBuffer[iFlag ] = lLen; cBuffer[iFlag ] = 0x30; cBuffer[iFlag ] = 0x30; sprintf(&cBuffer[iFlag],"%s",cTemp); iFlag =strlen(cTemp); cBuffer[iFlag ]=';'; //char ';' for (int i = 1;i char *str = "1234x5678"; // 如果x是為 0x00 則您在 Edit->Text 上只會看到 1234 Edit->Text = str;str 就如同您的 pcPackage 一旦這排字串中間有了一個 0x00 就會以它為結束碼。 蝦程速,有了 K.TOP 尊好。 |
aplay
一般會員 發表:2 回覆:10 積分:7 註冊:2004-10-14 發送簡訊給我 |
|
smartboss
初階會員 發表:19 回覆:93 積分:42 註冊:2004-12-29 發送簡訊給我 |
引言: 感謝您的回答,這樣的問題我並不擔心,因為我主要目的是要將此字串透過RS232交握。因為我一直想要避免使用FOR迴圈去傳送,看能否有其他較為簡潔的方法傳送。 然而目前小弟欲到的另一個難題是,我要接收下來的字串中一樣會含有0X00,這跟上述的問題雷同,但是其困難點在於我是否能聰明的得知字串中的空字元是我要的且不會被BCB自動截除空字元後的字串。 而我目前是使用VB的MSCOMM元件來使用,如果各位大大有好的方法請不另提供與指教。您不妨自己訂定一個所謂的結尾碼,因為不管它的值是否有0x00 它都是存在記億体中的,您只需將記憶体位址再往下一個位置指就可以取出0x00 後面的東東了,直到您讀到結尾碼時再停止。 蝦程速,有了 K.TOP 尊好。 |
aplay
一般會員 發表:2 回覆:10 積分:7 註冊:2004-10-14 發送簡訊給我 |
|
yorkland
高階會員 發表:2 回覆:138 積分:108 註冊:2004-12-17 發送簡訊給我 |
|
aplay
一般會員 發表:2 回覆:10 積分:7 註冊:2004-10-14 發送簡訊給我 |
|
fnk
高階會員 發表:40 回覆:149 積分:102 註冊:2004-01-02 發送簡訊給我 |
不好意思...插個花...
DestBuff = "1234x5678"; sprintf(OutBuff,%s%c,DestBuff,0x0d); // 若你能確定要傳送旳字串中不會有0x0d,則利用0x0d做為結束字元,是很好的選擇... CountLen = StrLen(OutBuff); // 計算字串有多長的副函式 int StrLen(char *OutBuff) { int i=0; while(OutBuff[i] != 0x0d) i ; return (i); }DestBuff是存放你原來的字串..裡面包括0x00的字元... OutBuff是在原來的字串後..加上一個結束位元..0x0d 最後...用自己寫的一個副函式StrLen()..來計算字串的長度... =========== 有興趣,就能進步 =========== |
jcjroc
高階會員 發表:21 回覆:279 積分:115 註冊:2002-09-18 發送簡訊給我 |
說實在的,只要是遠端電腦之間傳輸資料,我都會要求使用Binary的方式傳遞資料,如此才可以以最小的封包傳遞最多與最正確的資料,而且字串轉換本來就比較耗費資源,我實在想不出有哪個因素可以推翻上述的考慮.(當然爾,魚與熊掌是不可能兼得的,必須有所取捨) 而傳遞Binary資料就需要有檔頭與檢查碼,例如:
struct
{
unsigned long ulDataType;//資料類型定義
unsigned long ulStructSize;//檔頭結構大小
unsigned long ulPackDataLen;//封包長度(含檔頭)
unsigned long ulCheckSum;//檢查碼
}TranDataStruct;
上述是一個資料封包檔頭的概述,並不是通用.
CheckSum在對於不穩定的連線上(如RS232),有其必要性,可視狀況增加檢查的全面性(如CRC).
至於交握的時機端看一次的資料封包長度而定.
至於我個人的經驗是會在整個封包最前面再加入一個前導碼,此舉對於接收端處理所接收的資料時可以很快的判定是不是資料起始,而不用收了一堆到最後發現是垃圾. 以上就是我對你所提的問題的回答,講明一點就是改變傳遞的資料格式與封包,相對也避掉你所提的問題,不知這個回答你滿意嗎?
|
aplay
一般會員 發表:2 回覆:10 積分:7 註冊:2004-10-14 發送簡訊給我 |
引言: 不好意思...插個花... DestBuff = "1234x5678"; sprintf(OutBuff,%s%c,DestBuff,0x0d); // 若你能確定要傳送旳字串中不會有0x0d,則利用0x0d做為結束字元,是很好的選擇... CountLen = StrLen(OutBuff); // 計算字串有多長的副函式 int StrLen(char *OutBuff) { int i=0; while(OutBuff[i] != 0x0d) i ; return (i); } DestBuff是存放你原來的字串..裡面包括0x00的字元... OutBuff是在原來的字串後..加上一個結束位元..0x0d 最後...用自己寫的一個副函式StrLen()..來計算字串的長度...我測試了先進fnk的範例程式碼,解果好像也是一樣不能跳過結束字元, 然後結尾加上0x0d字元,假設DestBuff = "1234x5678";那麼OutBuff等 於1234\0\0x0d的結果,而長度也僅有4個字元長度。以下是我測試的程 式碼,若有哪裡錯誤請指正。 void __fastcall TForm1::Button1Click(TObject *Sender) { char aa[]= "1234567890"; aa[5] ='\0'; char cc[100]; char *bb=cc; long CountLen; sprintf(bb,"%s%c",aa,0x0d); CountLen = StrLen(bb); } //--------------------------------------------------------------------------- // 計算字串有多長的副函式 int StrLen(char *OutBuff) { int i=0; while(OutBuff[i] != 0x0d) i ; return (i); } |
aplay
一般會員 發表:2 回覆:10 積分:7 註冊:2004-10-14 發送簡訊給我 |
引言: 說實在的,只要是遠端電腦之間傳輸資料,我都會要求使用Binary的方式傳遞資料,如此才可以以最小的封包傳遞最多與最正確的資料,而且字串轉換本來就比較耗費資源,我實在想不出有哪個因素可以推翻上述的考慮.(當然爾,魚與熊掌是不可能兼得的,必須有所取捨) 而傳遞Binary資料就需要有檔頭與檢查碼,例如: struct { unsigned long ulDataType;//資料類型定義 unsigned long ulStructSize;//檔頭結構大小 unsigned long ulPackDataLen;//封包長度(含檔頭) unsigned long ulCheckSum;//檢查碼 }TranDataStruct; 上述是一個資料封包檔頭的概述,並不是通用. CheckSum在對於不穩定的連線上(如RS232),有其必要性,可視狀況增加檢查的全面性(如CRC). 至於交握的時機端看一次的資料封包長度而定. 至於我個人的經驗是會在整個封包最前面再加入一個前導碼,此舉對於接收端處理所接收的資料時可以很快的判定是不是資料起始,而不用收了一堆到最後發現是垃圾. 以上就是我對你所提的問題的回答,講明一點就是改變傳遞的資料格式與封包,相對也避掉你所提的問題,不知這個回答你滿意嗎?謝謝jcjroc先進的回答,以Binary傳遞資料是個很不錯的方法,也可以避開不必要的困擾(轉換與判斷)。可是以我目前的需求,其資料的規定封包並不是我能自訂的,封包中包含了不同的資料型態,有字串與ACSII碼,雖然我能將它轉換至Binary,但是卻要多了一個步驟,或許會使得問題更複雜,所以我目前並不想採用它。不過話說回來這樣的方式的確是不錯的選擇。 |
fnk
高階會員 發表:40 回覆:149 積分:102 註冊:2004-01-02 發送簡訊給我 |
對不起...
我錯了....
原因是因為 sprintf(bb,"%s%c",aa,0x0d);
也是判斷字串的結束位元 0x00...
所以...整合起來...字串會變成 "1234\0x00\0x0d"...
所以才會只有四個位元...
嗯....
所以...若你有辦法得知字串的長度...
那可以解決你的問題...
但...若無法得知字串的長度...
我現在想不出有什麼方法可以解決...>"<
不好意思... ===========
有興趣,就能進步
=========== 發表人 - fnk 於 2005/03/15 12:01:50
|
aplay
一般會員 發表:2 回覆:10 積分:7 註冊:2004-10-14 發送簡訊給我 |
引言:對不起... 我錯了.... 原因是因為 sprintf(bb,"%s%c",aa,0x0d); 也是判斷字串的結束位元 0x00... 所以...整合起來...字串會變成 "1234\0x00\0x0d"... 所以才會只有四個位元... 嗯.... 所以...若你有辦法得知字串的長度... 那可以解決你的問題... 但...若無法得知字串的長度... 我現在想不出有什麼方法可以解決...>"< 不好意思...fnk大大太客氣啦 ,有這個討論區是提供 大家可以討論事情的好地方阿,問題總是 會懸掛在醒目的地方,期盼著各位先進的 解救,大大們提供方法以供參考,不一定 是能完全解決發問人所訴求的,不過有這 樣的熱誠是世間所少有的。 關於0x00字串的問題,小弟昨天有找到解 決之道,不見得好,但或許堪用。 char OutBuf[255]=""; memmove (OutBuf,InBuf,sizeof(OutBuf)); 以上是將記憶緩衝區拷貝到指定的地方, 回傳之後,可依據指標的位址與陣列大小 (for loop get the char[i])進行判斷與 輸出。 如果說以字串(String)處理的話也是一樣會 受0x00的限制。 如果說各位大大有更好的方式或更精闢的方 法,希望能教導一下。 關於此題的得分我想應該是要給smartboss, 因為他點出了其中關鍵的因子(對小弟我), 但是其他大大的回答也是很不錯的另類思考 ,若我受益良多。 jcjroc大大的Binary的方式如果說有範例可 以參考,那真是造福了大家囉。 最後感謝之外還是感謝~ < >< > |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |