2015-05-26 33 views
0

我正在嘗試使用strcpy(buffer, "")來清除char緩衝區。 strcpy()似乎將隨機數字放在字符串中。在gdb中,我看到了緩衝區(received_message):strcpy向空字符串中添加隨機數

之前strcpy()電話:

通話
(gdb) print received_message 
$6 = "9210070627\000\000\000\000\000\000\000\000\000" 

strcpy()

(gdb) print received_message 
$8 = "\000\062\061\060\060\067\060\066\062\067\000\000\000\000\000\000\000\000\000" 

\060 ... \067 = 48 ... 65。

我的strcpy()調用代碼簡直是strcpy(received_message, "");,所以我不確定wha t正在發生。

我已經解決了實際問題,只是把一個空終止符,而不是試圖使字符串空,因爲我知道字符串的長度,但我仍然很好奇這裏發生了什麼。

編輯:似乎有些人想要更多的背景知道爲什麼我這樣做。我這樣做是因爲我使用zmq,它發送和接收沒有空終止符的字符串。我跑了一個問題在一個測試,我做了以下內容:

Send 1234 
Receive 1234 
Send 123 
Receive 1234 
Send 12345 
Receive 12345 
Send 1234 
Receive 12345 

什麼似乎是發生的事情是,我是重用我的緩衝區用於接收消息(received_message),如果以前的字符串這是保留值比收到的要長。

爲了解決這個問題,我想「沖洗」緩衝區,這意味着我想將它全部設置爲空字符。從閱讀其他答案,似乎strcpy(received_message, "")會做的伎倆,recived_message[0] = 0。但是,這些都不起作用,因爲它們只將第一個字符設置爲空。我知道memset()「沖洗」緩衝區的方法,但是讀取它的速度比strcpy(received_message, "")稍慢,所以沒有使用它。我想通過解決方案(並在下面顯示)避免將整個陣列設置爲memset(),所以我對它有點高興,儘管它可能沒有任何區別。

什麼讓我感到困惑的是,這個strcpy()調用替換什麼最初是通過與\06前綴個別數字,我有誤解爲ASCII字符,如\060而不是0前綴由\06字符串中的一些事實。

我有固定的問題,與接收的消息,因爲zmq_recv()返回而不空終止字符串長度,所以把一個空字符在收到郵件的末尾,我們只需要做

int received_length = zmq_recv(request_socket, received_message, 20, 0); 
received_message[received_length] = 0; 

在這種情況下,received messagechar的20個元素的數組,我擔心接收的郵件比這種情況下的時間要長。

解決問題之後,我還是好奇發生了什麼事情與我strcpy()電話,雖然我並沒有正確理解發生了什麼事。但我仍然很好奇,爲什麼這些數字的前綴是\06

回答

3

目前還不清楚你打算做,但代碼不正是你告訴它做的事。

C「字符串」是以空值結尾的一系列char元素。無論什麼後面,空值不是字符串的一部分。

通話之前,您的字符串:

「9210070627」(後面跟一個空值,以及一系列可能是緩衝區的部分或調試器的神器空值的,我們不知道)。

您的來電:

strcpy(buffer, "")(複印件空字符串到緩衝區,並與空值終止)

你的字符串後調用:

「」 - - 一個空字符串,後跟終止空值(加上「210070627」和空值作爲工件w這不是上面提到的字符串的一部分)。

因此,您的緩衝區現在包含一個空字符串,如您所指示的那樣。它還包含仍然是的原始數據,但buffer確實指向一個空字符串。 strlen(buffer) == 0

如果您打算刪除緩衝區的內容,即清零整個緩衝區,您應該嘗試memset()

+0

這使現在更有意義。我在考慮像'\ 060'這樣的字符是ASCII整數,但是你的回答讓我意識到它只是以'\ 06'爲前綴的原始值。我猜這個'\ 06'是一個整數或類似的指標?此外,是什麼導致'strcpy()'調用將數組更改爲像這樣格式化,而不是隻是一串數字? – danielunderwood

+0

@ danielu13不,它不是'\ 06',它的'\ 060',是八進制的,它是char''0''。 Simmilar其他值,檢查我的asnwer鏈接。 :-) –

+0

@danielu:'\ 060'是八進制符號的整數字面值,等於十進制的'48',恰好是字母「0」的ASCII值。 ('\ 061'爲'49'爲'''等等。)數組根本沒有「格式化」。但是調試器不知道終止'\ 0'後面的東西也應該被解釋爲字符串(*,因爲它不是字符串*的一部分),所以不是打印ASCII(並冒着很大的風險有趣但無意義的字符),它會打印八進制文字以告訴你內存中的原始數據。內存中的值完全不會被'strcpy()'改變。 – DevSolar

4

你不應該使用

strcpy(buffer, "") 

沖洗一個緩衝。它僅將""複製到目的地,並將其餘的區域buffer保留爲未觸及的

這就是爲什麼,你可以看到以前的值是保留

爲了闡述,我們可以看到,該buffer是有一個值"9210070627",在strcpy(buffer, "")之後,"9"\0代替,但是剩餘值中buffer persisit。

檢查ASCII表中的值。

也許,你想要的是

memset(buffer, 0, sizeof(buffer)); //buffer is char[] 

memset(buffer, 0, strlen(buffer)); //buffer is char* 
+0

或只是緩衝[0] = \ 0如果他正確使用字符串 – texasbruce

+0

@texasbruce但也不會_flush_整個緩衝區,對吧? –

+0

memset(buffer,0,buffer_size);最好是 memset(buffer,0,strlen(buffer))不應該被使用。緩衝區[0] = \ 0不是一個好主意,或者 –