2

这主要是:

std::ofstream rainbow_file("rainbow.bin", std::ios::binary);
rainbow_file.write((const char*) p.pass, password::PASSWORD_SIZE);
rainbow_file.write((const char*) h.hash_, hash::HASH_SIZE);

在哪里 :

class hash
{
public:
    static const size_t HASH_SIZE = 32;
    uint8_t hash_[HASH_SIZE];
...
}
// similar for pass

我在 Notepad++ 中打开 Rainbow.bin 文件,我看到我的通行证是通行证(字符 AZ、@、!、az、0-9)和哈希的二进制垃圾。稍后我会这样做:

std::ifstream rainbow_file("rainbow.bin", std::ios::binary);
rainbow_file.read((char*) p.pass, password::PASSWORD_SIZE);
rainbow_file.read((char*) h.hash_, hash::HASH_SIZE);

我将通行证作为二进制垃圾返回。我尝试了很多事情(比如打开两个流 - 一个不是二进制模式 - 并使用 seekg 分别移动文件指针,尝试各种强制转换等),但对于我的生活,我无法让它工作。我很好奇为什么。并且很沮丧。我在 npp 中重复一遍,我看到所有的东西都是有序的。

编辑:这些是不同的控制流,并且流被正确关闭()

编辑2:工作!仍然请参阅下面的答案和评论以了解更多的 C++ 方式

4

2 回答 2

1
std::ifstream rainbow_file("rainbow.bin", std::ios::binary);  /* OK */

rainbow_file.read((char*) p.pass, password::PASSWORD_SIZE);   /* KO */
rainbow_file.read((char*) h.hash_, hash::HASH_SIZE);

应替换为:

rainbow_file.read ( reinterpret_cast < char*> (&(p.pass)), password::PASSWORD_SIZE * sizeof(uint_8t));
rainbow_file.read ( reinterpret_cast < char*> (&(h.hash_)), hash::HASH_SIZE * sizeof(uint_8t));

这样你就不会假设 sizeof (uint_8t) == sizeof (char)。

在 C++ 中,h.hash_ 是一个类型为 uint_8t(&)[hash::HASH_SIZE] 的数组,而不是指针...您可以通过让编译器检查强制转换来轻松发现问题,但不幸的是,您使用了 C 风格演员,未检查。

永远不要在 C++ 程序中使用 C 风格转换方法!!!

但实际上你可以在纯 C++ 中做到这一点,没有错误:

std::ifstream rainbow_file("rainbow.bin", std::ios::binary);

rainbow_file >> p.pass >> h.hash_;
于 2012-05-28T03:39:53.277 回答
1

如果您的文件中使用了非 ascii char(似乎是二进制文件),则必须使用 std::noskipws 流操纵器。此外,您还可以显式指定要加载的每个字段的宽度,从而生成代码rainbow_file >> std::noskipws >> std::setw ( password::PASSWORD_SIZE ) >> p.pass >> std::noskipws >> std::setw ( hash::HASH_SIZE ) >> h.hash_;

@Nicol Bolas我没有假设 uint_8t 的类型大小,而是指针的大小!转换指针本质上是不安全的,我们对类型的真正内存布局了解多少?没有什么。这是强制转换非派生类型的指针不安全的唯一原因。我使用 reinterpret_cast 来通知其他开发人员以及编译器我知道我在做什么,reinterpret cast 的工作方式与日常使用中的静态转换相同。正如我所看到的,每个人都看到了这个把戏,所以我做得很好!

最后我必须重复那个p.pass 并且h.hash_不是 C++ 中的指针!!!!!!它是 POD,C 风格的演员不能告诉你,C++ 风格的...

于 2012-05-28T21:48:16.210 回答