2015-05-26 88 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不是一个好主意,或者 –