Хобрук: Ваш путь к мастерству в программировании

std::cout и printf удаляют символы из С++

Я загружаю файл с URL-адреса, используя socket.h, и когда я пытаюсь вывести содержимое буфера, я получаю только его часть. Вот файл 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] = '\0';
 std::cout  << "client: received data length " <<  dataLength << std::endl << bufIn;

Мой консольный вывод, когда я запускаю его -

HTTP для oref.org.il:

Отправлено. клиент: полученная длина данных 524
HTTP/1.1 200 OK
Cache-Control: max-age=4 Content-Length: 174 Content-Type:application/json
Последнее изменение: вторник, 15 июля 2014 г. 08:43:22 GMT
Допустимые диапазоны: байты
ETag: W/"6bad3d68a0cf1:2d5"
Сервер: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
> Дата: вторник, 15 июля 2014 г., 08:44:45 по Гринвичу
Set-Cookie: cookiesession1=KI4GAQVLKVW4JFN90R6B9GAANOO8HAYR;Path=/

��{

Пока... Когда я обнюхиваю пакеты, вывод -

{ «id»: «1405424602778», «название»: «», «данные»: [] }

Or :

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, поэтому менять ее нет смысла.
Спасибо!


  • Кодировка в вашем дампе, похоже, UTF16-LE, а не UTF-8. 15.07.2014
  • @JoachimIsaksson Я узнал от парня, что сайт использует UTF-16, но когда я попытался проверить кодировку с помощью функции PHP, он сказал, что это UTF-8. Попробую конвертировать с помощью iconv, спасибо 15.07.2014

Ответы:


1

Вы отправляете cout a const char* в bufIn, поэтому единственный способ, которым cout может судить о его длине, - это найти первый NUL-байт: ваши данные не ASCII, поэтому они достигают байтов "ff fe 7b 00" и останавливают свой вывод. Если вы хотите избежать этого, вы можете либо заставить NUL отправляться на терминал с помощью cout.write(bufIn, dataLength), либо перебирать данные, печатая символы с возможностью isprint() в обычном режиме и печатая, скажем, \восьмеричное значение или любое другое обозначение, которое вы нравится.

Кроме того, TCP — это протокол потока байтов, что означает, что любые данные, которые вы пытаетесь считать, могут быть доставлены вам в виде меньших секций с единственной необходимой степенью детализации на уровне байтов. Если вы получаете один раз и получаете только часть данных, вы должны зацикливаться и получать снова, пока не получите все, что ожидаете/нужно (или EOF/отключение/ошибка). Ваша задача — повторно собрать эти данные или иным образом обработать их в соответствии с вашими потребностями. Некоторые функции API позволяют блокировать до тех пор, пока не будет получено определенное количество байтов (или EOF/отключение/ошибка), но это ненормальное поведение. Прочтите справочную страницу для 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] = '\0';

Не самый чистый код, но это общая идея.

15.07.2014
  • Что ж, используя wireshark и сравнивая с dataLength, я заметил, что получаю только 525 байт, в то время как длина данных, указанная в Wireshark, составляет 579. Итак, что вы предлагаете? Спасибо, может быть, 54 байта - это заголовки или что-то в этом роде? 15.07.2014
  • @Yohonatan: все, что вам нужно сделать, это продолжать получать, пока больше нечего будет получать ... какой-то ориентировочный (непроверенный) отредактированный код, который должен направить вас на правильный путь. 15.07.2014
  • Что ж, использование cout.write просто решило это. Единственная проблема сейчас в том, что он меняет буквы на ����� ����� ����� ����� 15.07.2014
  • То, как именно они отображаются, зависит от вашей терминальной программы, но именно поэтому я говорю, что вы, вероятно, захотите перебирать символы по одному, используя if (std::isprint(c)) std::cout << c; else std::cout << '\\' << std::oct << std::setw(3) << std::setfill('0') << (int)c; или подобное. 15.07.2014
  • Новые материалы

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..