1

我正在尝试编写一个简单的 C++ 程序来打开一个 torrent 文件(通过 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;
}
4

3 回答 3

1

通过使用wifstream,您将文件视为 UTF-16,这是错误的。torrent规范清楚地表明它适用于字节字符串,而不是 Unicode 字符。我的印象是 BT 也不关心字符集(代码页),这取决于客户端程序的解释。文件名只是字节串,没有附加任何含义。

种子文件不是文本文件,因为它包含二进制哈希值,因此尝试将其作为文本文件进行读写并不是一个好主意。最好实现一个编码解析器,这样您就可以在输出哈希值之前将它们转换为十六进制。

于 2010-07-02T05:18:56.387 回答
1

读取文件时有一个经典的基本错误:

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。这个错误通常意味着上面的循环会打印最后一行两次(取决于 Line 的设置方式)。

真正的解决方案是将getline放入while中。

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

如果 getline() 读取一个 EOF,那么它会在 File 中设置一个标志。getline() 的结果是对流对象(文件)的引用,当它在布尔上下文中使用时,如果一切正常,它会转换为可转换为 true 的值,如果出现问题则转换为 false(如 EOF) . 这意味着当您到达 EOF 时不会输入循环体。

您需要注意的另一件事是终端的属性和文件的格式。如果有不匹配,那么看起来显示的字符不匹配..

于 2010-06-20T20:59:02.760 回答
0

正如 Neil Mayhew 在他的回答中提到的,将整个 .torrent 文件视为文本并没有多大意义,因为它包含二进制数据。

您应该重新考虑以下几点:

  • 不要使用宽字符流,因为文件大小可能不是sizeof(wchar_t).
  • read()在这种情况下更可取,getline()因为 .torrent 文件不使用基于行的文本格式。
  • 打开文件时使用该ios::binary标志,否则您将获得不需要的行尾转换(这发生在 Windows 上)
  • cout出于同样的原因,您还应该切换到二进制模式。
于 2010-07-21T04:04:18.010 回答