【问题标题】:Conceptual Problems with Iterator迭代器的概念问题
【发布时间】:2009-06-23 02:40:51
【问题描述】:

我正在尝试编写我的第一个迭代器类/容器类型。基本上,我希望能够遍历一个文件,将文件即时转换为 HEX,并将结果传递到 boost::xpressive 库。我不想一次性转换为 RAM 中的字符串,因为我需要能够处理的一些文件大于预期的系统 RAM(多 GB)。

这是我的代码的样子。我正在使用 MSVC++ 2008。

迭代器的标题:

class hexFile;

class hexIterator : public std::iterator<std::bidirectional_iterator_tag, wchar_t>
{
    hexFile *parent;
    __int64 cacheCurrentFor;
    wchar_t cacheCharacters[2];
    void updateCache();
public:
    bool highCharacter;
    __int64 filePosition;
    hexIterator();
    hexIterator(hexFile *file, bool begin);
    hexIterator operator++();
    hexIterator operator++(int)
    {
        return ++(*this);
    }
    hexIterator operator--();
    hexIterator operator--(int)
    {
        return --(*this);
    }
    bool operator==(const hexIterator& toCompare) const;
    bool operator!=(const hexIterator& toCompare) const;
    wchar_t& operator*();
    wchar_t* operator->();
};

迭代器的实现:

#include <stdafx.h>
class hexFile;
hexIterator::hexIterator()
{
    parent = NULL;
    highCharacter = false;
    filePosition = 0;
}
hexIterator::hexIterator(hexFile *file, bool begin) : parent(file)
{
    if(begin)
    {
        filePosition = 0;
        highCharacter = false;
    } else
    {
        filePosition = parent->fileLength;
        highCharacter = true;
    }
}

hexIterator hexIterator::operator++()
{
    if (highCharacter)
    {
        highCharacter = false;
        filePosition++;
    } else
    {
        highCharacter = true;
    }
    return (*this);
}

hexIterator hexIterator::operator--()
{
    if (highCharacter)
    {
        highCharacter = false;
    } else
    {
        filePosition--;
        highCharacter = true;
    }
    return (*this);
}

bool hexIterator::operator==(const hexIterator& toCompare) const
{
    if (toCompare.filePosition == filePosition &&
        toCompare.highCharacter == highCharacter)
        return true;
    else return false;
}

bool hexIterator::operator!=(const hexIterator& toCompare) const
{
    if (toCompare.filePosition == filePosition &&
        toCompare.highCharacter == highCharacter)
        return false;
    else return true;
}
wchar_t& hexIterator::operator*()
{
    updateCache();
    if (highCharacter)
        return cacheCharacters[1];
    return cacheCharacters[0];
}

wchar_t* hexIterator::operator->()
{
    updateCache();
    if (highCharacter)
        return cacheCharacters + 1;
    return cacheCharacters;
}

void hexIterator::updateCache()
{
    if (filePosition == cacheCurrentFor)
        return;
    BYTE rawData;
    DWORD numberRead;
    LONG lowValue = static_cast<LONG>(filePosition);
    LONG highValue = static_cast<LONG>(filePosition >> 32);
    SetFilePointer(parent->theFile, lowValue, &highValue, FILE_BEGIN);
    if (!ReadFile(parent->theFile, &rawData, 1, &numberRead, 0))
        throw std::runtime_error(eAsciiMsg("Error reading from file."));
    static const wchar_t hexCharacters[] = L"0123456789ABCDEF";
    cacheCharacters[0] = hexCharacters[rawData & 0x0F];
    cacheCharacters[1] = hexCharacters[rawData >> 4];
    cacheCurrentFor = filePosition;
}

容器标题

class hexFile {
public: 
    HANDLE theFile;
    unsigned __int64 fileLength;
    hexFile(const std::wstring& fileName)
    {
        theFile = CreateFile(fileName.c_str(),GENERIC_READ,FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,NULL,NULL);
        if (theFile == INVALID_HANDLE_VALUE)
        {
            throw std::runtime_error(eAsciiMsg("Could not open file!"));
        }
        BY_HANDLE_FILE_INFORMATION sizeFinder;
        GetFileInformationByHandle(theFile, &sizeFinder);
        fileLength = sizeFinder.nFileSizeHigh;
        fileLength <<= 32;
        fileLength += sizeFinder.nFileSizeLow;
    };
    ~hexFile()
    {
        CloseHandle(theFile);
    };
    hexIterator begin()
    {
        hexIterator theIterator(this, true);
        return theIterator;
    };
    hexIterator end()
    {
        hexIterator theIterator(this, false);
        return theIterator;
    };
};

但是,无论我尝试什么测试用例,正则表达式都不会匹配。我假设这是我的迭代器的一些概念问题。在所有情况下它都应该是一个恒定的双向迭代器。

我遗漏了什么,或者有更简单的方法吗?

比利3

【问题讨论】:

    标签: c++ stl iterator


    【解决方案1】:

    这是一段需要阅读的代码;乍一看,我什么也没看到。

    对于实现说明,这听起来更像是一个 iostream 而不是一个迭代器,使用缓冲可能会明显更快。 Boost 有一个库来帮助实现those

    如果您想使用迭代器,他们也有一个 library 来帮助您,它可以确保您获得所需的所有方法,同时大大简化实现。

    对于调试,我会尝试进行单元测试;这应该有希望指出问题;从一些小的东西开始,比如一个有两个字符的文件,在调试器中遍历以查看发生了什么,然后迭代直到通过所有内容。

    【讨论】:

    • 问题是 boost::xpressive 不知道如何使用 iostream。
    • 经过测试,迭代器产生正确的结果。这不是迭代器代码本身的错误,而是 boost::xpressive 内部的断言失败。
    • 您仍然可以将其实现为 iostream 过滤器(如 base64 过滤器)并在输入上使用 istream_iterator。只是我的 2 美分 :)
    【解决方案2】:

    operator++(int) 应该根据operator++() 定义,而不是相反。尝试切换它们。 operator-- 也一样。

    【讨论】:

    • 编辑了以上内容以反映差异。
    【解决方案3】:

    嗯...原来我是个彻头彻尾的白痴。

    boost::xpressive::regex_match(fileInstance.begin(), fileInstance.end(), results, internalRegex);

    嗯……我的意思是

    boost::xpressive::regex_search(fileInstance.begin(), fileInstance.end(), results, internalRegex);

    迭代器从来没有出错过。

    抱歉浪费了别人的时间, 比利3

    【讨论】:

      【解决方案4】:

      尝试使用Boost::transform_iterator

      【讨论】:

      • 问题是,当转换为十六进制时,每个输入字符都会返回两个字符。因此,将 ++ 和 -- 运算符传递给下面的迭代器不会按预期运行......这需要明确处理。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      • 2022-10-14
      • 2012-03-20
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多