Чтение и вывод возможного содержимого торрента Unicode в C ++? - PullRequest
1 голос
/ 21 июня 2010

Я пытаюсь написать простую программу на C ++, чтобы открыть торрент-файл (пропущенный через argv [1]), прочитать все его, а затем дословно распечатать содержимое всего файла без изменений, необходимо распечататькопия оригинального торрента.Проблема в том, что некоторые торренты могут содержать японский, русский и т. Д. (Имена файлов, описание и т. Д.) ... И, конечно, стандартные торрент-данные с хешами и еще много чего.Каков наилучший способ сделать это?То, что у меня есть, пока выводит только часть содержимого, и кажется, что оно неправильно читает или печатает данные ... Это искажено или что-то в этом роде:

#include "stdafx.h" 
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

#if defined(UNICODE)
    #define _tcout wcout
#else
    #define _tcout cout
#endif

int _tmain(int argc, TCHAR* argv[])
{
    wifstream File(argv[1]);
    wstring Line;

    while(!File.eof() )
    {
        getline(File, Line);

        _tcout << Line << endl;
    }
    File.close();
    return 0;
}

Ответы [ 3 ]

1 голос
/ 02 июля 2010

Используя wifstream, вы рассматриваете файл как UTF-16, что неверно. Спецификация torrent ясно говорит, что он работает со строками байтов , а не с символами Unicode. У меня складывается впечатление, что BT также не заботится о наборе символов (кодовой странице), оставляя это до интерпретации клиентской программы. Имена файлов - это просто строки байтов без какого-либо значения.

Торрент-файл не является текстовым файлом, поскольку он содержит двоичные значения хеш-функции, поэтому попытка прочитать и записать его как текстовый файл не является хорошей идеей. Было бы лучше реализовать синтаксический анализатор bencoding , чтобы можно было преобразовывать значения хеш-функции в шестнадцатеричные перед их выводом.

1 голос
/ 21 июня 2010

У вас есть классическая базовая ошибка при чтении файла:

while(!File.eof() )
{
    getline(File, Line); // If this line fails (ie you reach EOF)
                         // Then you still print out the Line (whoes value is undefined)

    _tcout << Line << endl;
}

Помните, что второй-последний getline будет читать (но не включая) EOF.Последний звонок будет читать только EOF.Эта ошибка обычно означает, что вышеприведенный цикл напечатает последнюю строку дважды (в зависимости от того, как установлена ​​строка).

Реальное решение - поместить getline в while.

while(getline(File, Line))
{
    _tcout << Line << endl;
}

Если getline () читает EOF, тогда он устанавливает флаг в File.Результатом getline () является ссылка на объект потока (File), когда он используется в логическом контексте, он преобразуется в значение, которое можно преобразовать в true, если все в порядке, или false, если что-то пошло не так (как в EOF),Это будет означать, что тело цикла не будет введено, когда вы достигнете EOF.

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

0 голосов
/ 21 июля 2010

Как отметил Нейл Мэйхью в своем ответе, рассматривать весь файл .torrent как текст не имеет особого смысла, поскольку он содержит двоичные данные.

Вам следует пересмотреть следующие пункты:

  • Не используйте широкие потоки символов, так как размер файла не может быть кратным sizeof(wchar_t).
  • read() предпочтительнее getline() в этом случае, так как .torrent-файлы не используют строчный текстовый формат.
  • Используйте флаг ios::binary при открытии файла, иначе вы получите нежелательное преобразование конца строки (это происходит в Windows)
  • Вы должны также переключить cout в двоичный режим по той же причине.
...