将ASCII转换为无符号Int和反之亦然

时间:2014-03-11 13:06:58

标签: c++ ascii

我正在阅读每行上有几个不同字段的大文件。通过类比,您可以将文件的每一行视为代表员工,其中一个字段包含它们所在的部门名称。但是,部门名称可以由任意一组4-5个ASCII字符组成(例如, " 1234"," ABCD"," P + 0 $ i"。

目前,我(天真地)将字符存储为std :: string,但我注意到我已经进行了大量耗时的字符串比较。因此,我想从文件中读取字段,将字符串转换为数字(可能是unsigned int?),然后进行许多数字比较(并避免字符串比较)。当然,我需要一种方法将数字转换回字符串以便输出。

我的大多数在线搜索都会显示"将字符串转换为数字"讨论了使用stringstream将数字字符串转换为某种类型的int的用法。这不是特别有用,我似乎无法找到合适的搜索查询来找到解决方案。有人可以请我指向相关来源或提供执行此转换的方法吗?

4 个答案:

答案 0 :(得分:1)

好吧,如果你有最多5个ASCII字符,那么最简单的方法是用你喜欢的任何字符将其填充到8,然后*reinterpret_cast<uint64_t*>(the_id.data())

如果要将字符表示拟合为32位int,则需要做更多的工作:简单地丢弃高位(可能因为ASCII码为0-127)仍然留下7 * 5 = 35位 - 对于32位类型来说太多了。假设id不包含任何控制代码(即ASCII代码0-31),您可以使用 base-96 encoding 来实现打包:

unsigned base = 128 - 32;
// pad c out to 5 characters if necessary.
unsigned idnum = (((((c[0] - 32) * base + (c[1] - 32)) * base + (c[2] - 32)) * base + (c[3] - 32)) * base + (c[4] - 32)) * base + c[5] - 32;

您可能会发现使用循环更容易阅读:

unsigned idnum = 0;
for (size_t i = 0; i < 5; ++i)
{
    idnum *= base;
    idnum += c[i] - ' ';
}

使用% base将数字打包回字符串值以获取最后一位数字,然后/ base准备获取下一位数字....

答案 1 :(得分:0)

  1. 使用部门名称创建地图 - &gt;某处的整数映射。根据部门名称的固定方式,可以从配置文件中读取它们,也可以静态定义地图。之后创建逆映射以映射整数 - &gt;需要时串。
  2. 在读取文件时,查找映射中的关联键并将其存储在数据结构中。
  3. 如果需要,请在反向地图中查找部门名称

答案 2 :(得分:0)

鉴于std :: string相等操作对于任意长度的数据实际上是有效的,并且您需要保留实际的字符串值,我觉得您可能希望在别处寻找性能改进。查看您的要求,您似乎只需要为对象提供更好的搜索效率。 std::unordered_map容器可能是一个很好的候选者。它是一个关联容器,具有通过密钥查找的恒定时间。您可以将其他数据集存储为unordered_map的值类型,并将关联键设置为您想要查找的内容。以下是一些类型的示例,这些类型可以通过字符串查找数据的匹配子集。

struct Employee;
typedef std::vector<std::shared_ptr<Employee>> Employees;
typedef std::unordered_map<std::string, Employees>  EmployeeByLookup;

然后,您可以查找匹配给定键值的所有员工。

static EmployeeByLookup byDepartment;

Employees& GetDepartmentList(const std::string& department)
{
    return byDepartment[department];
}

如果您需要按值而不是通过关联键查找对象,那么我建议您查看std::unordered_set。它还具有查找的恒定时间的平均复杂度。如果需要优化内部哈希性能,可以为对象创建自己的哈希函数。

我使用unordered_map示例创建了simple application。看看你是否感兴趣。

答案 3 :(得分:-1)

C ++ 11有std::stoi。除此之外,您可以使用字符串流进行转换:

std::istringstream iss("1234");
int x;
if ( iss >> x )
    std::cout << "Got " << x << "\n";
else
    std::cout << "String did not contain a number\n";

您可以像iss一样从cin进行其他流提取。

我不确定为什么你认为stringstream建议“不是很有用”?