65.9K
CodeProject 正在变化。 阅读更多。
Home

整数的字面量转换器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.18/5 (5投票s)

2005年5月13日

CPOL

3分钟阅读

viewsIcon

63998

downloadIcon

1450

一个辅助类,用于在十进制、八进制、二进制和十六进制之间转换整数文字。

LiteralConversion_gui.png

LiteralConversion_cli.png

引言

电子工程师经常需要绘制从电子仪器(例如示波器)观察到的实验数据。 通常,数据以一种格式(例如十六进制)存储,而绘图软件需要另一种输入格式(例如十进制)。 这很不方便。 我最终决定将转换包装到一个 C++ 类中:CLiteralConverter。 实际上,整数文字通常以四种形式出现:十进制、八进制、十六进制和二进制文字。 因此,CLiteralConverter仅提供这四种格式之间的转换。

背景

CLiteralConverter并没有采用任何手工算法,而是完全利用了标准 iostream 库的功能。 这个想法很简单

1. 分词

使用 BOOST Tokenizer 库,可以轻松解析原始数据字符串并将其分解为转换单元。 下面显示了一个典型的用法

// 1. initialise a seperator functor
boost::char_separator<char> sep(", ;");
// 2. initialise the tokenizer with the string and the seperator
boost::tokenizer
<boost::char_separator<char> > tok("o,riginal str; ing",sep);
// 3. iterate to get each tokenized result.
boost::tokenizer
<boost::char_separator<char> >::iterator itr, itr_end;
itr = tok.begin();
itr_end = tok.end();
for(; itr != itr_end; ++itr)
{
    ...
}

2. 转换和存储值

分词后,将单元转换为std::size_t值并存储为std::vector<std::size_t>。 此步骤借助流操作符完成:std::hexstd::octstd::dec。 然后我们可以将单元读取为十六进制、八进制和十进制值。 但是,不支持二进制表示法。 幸运的是,我们可以使用类bitset读取二进制。 下面演示了用法

// for reading hex, dec and oct
stringstream ss;
std::ios::fmtflags fmt;
size_t lVal;

fmt = std::ios::hex/* std::ios::dec, std::ios::oct */;
ss << "55";
ss.setf(fmt, std::ios::basefield);
ss >> lVal;

// for reading binary 
bitset<numeric_limits<size_t>::digits> bt("101010");
lVal = bt.to_ulong();

...

3. 输出

现在没有更多魔法了。 再次使用流的操作符,这次用于写入。 对于二进制文件,只需调用 to_string() 方法。

使用代码

只需在普通的 C++ 类中使用代码,如下所示

#include "LiteralConverter.h"

...

// 1. declare an object
CLiteralConverter lc;

// 2. assign the input string, using the default delimiters(",; :h")
lc.SetString("5 aa bb cc dd 2", CLiteralConverter::HEX);

// 3. get the converted string, using the default delimiters("; ")
string s;
s = lc.GetString(CLiteralConverter::DEC);
s = lc.GetString(CLiteralConverter::OCT);
s = lc.GetString(CLiteralConverter::BIN);
s = lc.GetString(CLiteralConverter::HEX);

// or: get the value for customizeed treatment
vector<size_t> vl;
lc.GetValue(vl);

...

CLiteralConverter 函数

设置原始数据

调用这些函数来设置原始数据、格式和分隔符

  • void SetString(const string& s, _FORMAT_ format, const string& sDelim = ",; :h")
  • void SetString(ifstream& f, _FORMAT_ formatsDelim, const string& sDelim = ",; :h")

    第一个原型接受一个std::string类型的字符串作为输入,而第二个原型接受一个std::ifstream。 请确保在传入之前已正确初始化f。 建议在调用SetString()之前断言f.is_open()format可以是CLiteralConverter::HEXCLiteralConverter::DECCLiteralConverter::OCTCLiteralConverter::BIN

获取转换后的数据

调用此函数以获取原始数据、格式和分隔符

  • string GetString(_FORMAT_ format, const string& sDelim = "; ")

    此函数返回转换后的数据字符串,给定所需的格式。 format可以是CLiteralConverter::HEXCLiteralConverter::DEC,CLiteralConverter::OCTCLiteralConverter::BIN

还提供了一些更具体的变体

  • string GetDec(const string& sDelim = "; ")获取十进制输出。
  • string GetHex(const string& sDelim = "; ")获取十六进制输出。
  • string GetOct(const string& sDelim = "; ")获取八进制输出。
  • string GetBin(const string& sDelim = "; ")获取二进制输出。

在对数据进行自定义操作的情况下,可以调用GetValue(vector<size_t>& vValue)来获取存储的值。

尽情享用!

参考文献

  1. 免费的同行评审可移植 C++ 源代码库.
  2. CKCSideBannerWnd:一个 MFC Banner 控件,可以为大多数窗口添加专业外观... 作者 Peter Mares。 此类用于使演示应用程序看起来更好。 谢谢 Peter。

修订历史

  1. 版本 1.0, 2005-05-13
    • - 首次发布
  2. 版本 1.1, 2009-08-19
    • - 修复了 long 类型的溢出错误,请改用 size_t。
      - 添加了控制台演示应用程序
      - 将演示应用程序更新到 VS2008
© . All rights reserved.