将从二进制文件读取的字符串转换为整数

时间:2019-01-07 16:11:40

标签: c++ binaryfiles atoi

我有一个二进制文件。我正在使用fstream一次读取16个字节。

我想将其转换为整数。我尝试过atoi。但是没有用。 在python中,我们可以使用stringobtained.encode('utf-8')转换为字节流,然后使用int(bytestring.hex(),16)将其转换为int来实现。我们应该按照python一样完成elloborate步骤,还是可以直接转换它?

ifstream file(binfile, ios::in | ios::binary | ios::ate);
if (file.is_open())
{

    size = file.tellg();
    memblock = new char[size];
    file.seekg(0, ios::beg);
    while (!file.eof())
    {
        file.read(memblock, 16);            
        int a = atoi(memblock); // doesnt work 0 always
        cout << a << "\n";
        memset(memblock, 0, sizeof(memblock));
    }
    file.close();

编辑:

这是文件的示例内容。

53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00
04 00 01 01 00 40 20 20 00 00 05 A3 00 00 00 47
00 00 00 2E 00 00 00 3B 00 00 00 04 00 00 00 01

我需要一次将其读取为16个字节,即32位十六进制数字(即示例文件内容中的一行)并将其转换为整数。 因此,当阅读 53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00 时,我应该得到 110748049513798795666017677735771517696

但是我做不到。即使尝试strtoull,我也总是得到0。我读错文件了吗,还是我丢失了什么?

3 个答案:

答案 0 :(得分:1)

您在这里遇到许多问题。首先是C ++没有标准的128位整数类型。您也许可以找到编译器扩展,例如参见Is there a 128 bit integer in gcc?Is there a 128 bit integer in C++?

第二个原因是您尝试解码原始字节而不是字符串。 atoi将在遇到的第一个非数字字符处停止,第256个字节中的246次将是第一个字节,因此它返回零。如果您很不幸,您将读取16个有效数字,而atoi将开始读取未初始化的内存,从而导致未定义的行为。

无论如何您都不需要atoi,您的问题要比这简单得多。您只需要将16个字节组合成一个整数,就可以使用shift和or运算符来完成。唯一的麻烦是read想要一个char类型,该类型可能会被签名,并且您需要未签名的字节。

ifstream file(binfile, ios::in | ios::binary);
char memblock[16];
while (file.read(memblock, 16))
{
    uint128_t a = 0;
    for (int i = 0; i < 16; ++i)
    {
        a = (a << 8) | (static_cast<unsigned int>(memblock[i]) & 0xff);
    }
    cout << a << "\n";
}
file.close();

答案 1 :(得分:0)

16个十六进制数字表示结果可以是8个字节长。因此public static ResponseEntity<String> makeRequest() { ResponseEntity<String> response = null; try { RestTemplate restTemplate = new RestTemplate(); response = restTemplate.exchange(URI, HttpMethod.GET, null, String.class); }catch (HttpStatusCodeException e) { System.out.println(e.getStatusCode()); }catch (Exception e) { e.printStackTrace(); } return response; } 不起作用。我们不能将基数赋给atoi,它返回的int通常是4个字节的整数。我们可以使用的可能是std::stoull

示例:

atoi
  

188750927691774

答案 2 :(得分:0)

该数字是二进制数,您想要的是:

    short value ;
    file.read(&value, sizeof (value));            

取决于文件的写入方式和处理器,您可能必须使用位操作来反转值中的字节。