std::cout和printf将从c++中删除字符

std::cout and printf are dropping chars out C++

本文关键字:删除 字符 c++ printf cout std 将从      更新时间:2023-10-16

我正在使用socket.h从url下载文件,当我试图输出缓冲区的内容时,我只得到它的一部分。这是to文件,一个基本的json文件。http://82.80.47.90/WarningMessages/alerts.json

相关代码-

 size_t MAX_DATA_LENGTH = 50001;
 char bufIn[MAX_DATA_LENGTH];
 dataLength = recv(sockfd, bufIn, MAX_DATA_LENGTH-1, 0);
 bufIn[dataLength] = '';
 std::cout  << "client: received data length " <<  dataLength << std::endl << bufIn;

运行时的控制台输出-

HTTP for oref.org.il:

发送。客户端:收到数据长度524
HTTP/1.1 200 OK
Cache-Control: max-age=4内容长度:174内容类型:application/json
最后修改日期:2014年7月15日星期二08:43:22 GMT
Accept-Ranges:字节
ETag: W/6 bad3d68a0cf1:2d5"
服务器:microsoft iis/6.0
X-Powered-By: ASP。净
日期:星期二,2014年7月15日08:44:45 GMT
Set-Cookie: cookiesession1=KI4GAQVLKVW4JFN90R6B9GAANOO8HAYR;Path=/

��{

而…当我嗅探数据包时,输出是-

{" id ":"1405424602778","称号 " : " ", " 数据 " : [] }

或:

0000   ff fe 7b 00 20 00 0d 00 0a 00 22 00 69 00 64 00  ..{. .....".i.d.
0010   22 00 20 00 3a 00 20 00 22 00 31 00 34 00 30 00  ". .:. .".1.4.0.
0020   35 00 34 00 32 00 34 00 36 00 30 00 32 00 37 00  5.4.2.4.6.0.2.7.
0030   37 00 38 00 22 00 2c 00 0d 00 0a 00 22 00 74 00  7.8.".,.....".t.
0040   69 00 74 00 6c 00 65 00 22 00 20 00 3a 00 20 00  i.t.l.e.". .:. .
0050   22 00 e4 05 d9 05 e7 05 d5 05 d3 05 20 00 d4 05  "........... ...
0060   e2 05 d5 05 e8 05 e3 05 20 00 d4 05 ea 05 e8 05  ........ .......
0070   e2 05 d4 05 20 00 d1 05 de 05 e8 05 d7 05 d1 05  .... ...........
0080   20 00 22 00 2c 00 0d 00 0a 00 22 00 64 00 61 00   .".,.....".d.a.
0090   74 00 61 00 22 00 20 00 3a 00 20 00 5b 00 5d 00  t.a.". .:. .[.].
00a0   0d 00 0a 00 7d 00 0d 00 0a 00 0d 00 0a 00        ....}.........
我真的很感激你的帮助。我试图改变编码,但编码是UTF-8,所以没有改变它的意义。
谢谢!

您将cout a const char*发送到bufIn,因此cout可以判断其长度的唯一方法是找到第一个NUL字节:您的数据不是ASCII,因此它击中"ff 7b 00"字节并停止其输出。如果您想避免这种情况,您可以使用cout.write(bufIn, dataLength)强制将null发送到终端,或者对数据进行迭代,正常打印isprint()可字符并打印 八进制值或您喜欢的任何其他符号。

此外,TCP是一个字节流协议,这意味着无论你试图读取什么数据,都可以在字节级别上以更小的粒度传递给你。如果你接收一次,只得到部分数据,你应该循环和接收再次,直到你得到所有你期望/需要(或EOF/断开/错误)。您的工作是重新组合这些数据或以其他方式处理它们以满足您的需求。一些API函数确实允许您阻塞,直到检索到特定数量的字节(或EOF/disconnect/error),但这不是正常的行为。阅读recv的手册页并查看一些示例,但总结如下:

size_t MAX_DATA_LENGTH = 50001;
char bufIn[MAX_DATA_LENGTH];
size_t position = 0;
size_t dataLength;
while ((dataLength = recv(sockfd, bufIn + position, MAX_DATA_LENGTH-position-1, 0)) > 0)
    position += dataLength;
dataLength = position;
bufIn[dataLength] = '';

不是最干净的代码,但这就是总体思路。