【问题标题】:std::map with a char[5] key that may contain null bytes带有可能包含空字节的 char[5] 键的 std::map
【发布时间】:2011-05-24 21:47:53
【问题描述】:

密钥是二进制垃圾,我只将它们定义为chars,因为我需要一个 1 字节数组。
它们可能包含null 字节。

现在的问题是,当我有两个键时:ab(0)aab(0)b(0)null 字节),map 将它们视为字符串,认为它们相等而我不获得两个唯一的map 条目。

解决这个问题的最佳方法是什么?

【问题讨论】:

  • char[5]std::map<> 的无意义键类型。为什么要避开std::string/std::vector<char>/std::array<char, 5>
  • 如何声明地图?怎么往里面插入数据?
  • 只需要1字节的数组,为什么还要声明5字节的key?
  • @ildjarn:std::string 因为它以空字节结尾,std:vector 因为我还没有尝试过,std:array 因为它像 std::string 一样工作。 @Rob:我的意思是一组术语,每个 1 字节。
  • @GeorgeStephanos :我不确定您所说的“以空字节结尾”是什么意思——std::string 完全支持嵌入的空字符,std::vector<>std::array<> 也是如此...

标签: c++ stl char stdmap


【解决方案1】:

为什么不使用std::string 作为键:

//must use this as:
std::string key1("ab\0a",4); 
std::string key2("ab\0b",4); 
std::string key3("a\0b\0b",5); 
std::string key4("a\0\0b\0b",6); 

第二个参数应该表示 c 字符串的大小。以上都使用了这个构造函数:

string ( const char * s, size_t n );

description 其中是这样的:

内容被初始化为由 s 指向的字符数组中的前 n 个字符组成的字符串的副本。

【讨论】:

    【解决方案2】:

    使用std::array<char,5> 甚至更好(如果您真的想将键作为二进制值处理)std::bitset

    【讨论】:

    • 我忘了说我已经尝试过 std::array 并且它的工作方式与 char* 和 std::string 一样。至于 std::bitset,我不知道如何将它作为原始数据写入文件(我需要它)。
    【解决方案3】:

    如果你真的想使用char[5] 作为你的键,考虑编写你自己的比较类来正确地比较键。 map 类需要其中之一才能组织其内容。默认情况下,它使用的版本不适用于您的密钥。

    这是the map class 上的一个页面,其中显示了map 的参数。您可能想编写自己的Compare 类来替换less<Key>,这是map 的第三个模板参数。

    【讨论】:

      【解决方案4】:

      如果您只需要区分它们而不依赖于字典顺序,则可以将每个键视为 uint64_t。这样做的好处是,您可以轻松地将 std::map 替换为 hashmap 实现,并且您无需手动执行任何操作。

      否则,您也可以像这样编写自己的比较器:

      class MyKeyComp
      {
        public:
        operator()(char* lhs, char* rhs)
        {
          return lhs[0] == rhs[0] ? 
             (lhs[1] == rhs[1] ? 
             (lhs[2] == rhs[2] ? 
             (lhs[3] == rhs[3] ? lhs[4] < rhs[4]) 
             : lhs[3] < rhs[3]) 
             : lhs[2] < rhs[2]) 
             : lhs[1] < rhs[1]) 
             : lhs[0] < rhs[0];
        }
      };
      

      【讨论】:

      • 但是,请参阅std::lexicographical_compare
      • 我确实依赖于排序,我认为我只能添加一个比较器进行排序(如果更少,则为 true,如果更多,则为 false)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多