将std :: string存储到C ++中的Big Integer的int []中

时间:2017-06-07 09:47:14

标签: c++ c++11 casting

我正在尝试为BigInteger值创建自己的类。在此类中,Big Integer由unsigned int ints[capacity]组成,我有以下代码将std::string转换为BigInteger

void FromByteString1(const std::string& buf) {
    int mask[] = {0, 8, 16, 24};
    int validMask = 0xff;
    size_t currentMask = 0, currentIndex = 0;
    for (register size_t i = 0; i < buf.size(); ++i) {
        int tmp = (int) buf[i];
        data[currentIndex] |= ((tmp << mask[currentMask]) & (validMask << mask[currentMask]));
        if (++currentMask == 4) {
            currentMask = 0;
            ++currentIndex;
        }
    }
}

我尝试使用union { char[4] chars; int value; }解决此问题,但它什么也没给我。

这是我的输出:

enter image description here

以下是测试项目的完整代码&#34; Convertor&#34;,用于解决此问题:

#include <iostream>
#include <iomanip>
#include <bitset>

#define Write(message) std::cout << message
#define WriteLine(message) std::cout << message << std::endl
#define WriteEndl() std::cout << std::endl

#define WIDTH_STR 9
#define WIDTH_INT 33

void ShowStringChars(const std::string& str) {
    for (size_t i = 0; i < str.length(); ++i)
        Write( std::setw(WIDTH_STR) << str[i] );
    WriteEndl();
}

void ShowStringCodes(const std::string& str) {
    for (size_t i = 0; i < str.length(); ++i)
        Write( std::setw(WIDTH_STR) << (int)str[i] );
    WriteEndl();
}

void ShowStringCodesBin(const std::string& str) {
    for (size_t i = 0; i < str.length(); ++i) {
        std::bitset<8> bites( (int)str[i] );
        Write( std::setw(WIDTH_STR) << bites );
    }
    WriteEndl();
}

void ShowIntValues(int* arr, size_t length) {
    for (size_t i = 0; i < length; ++i)
        Write( std::setw(WIDTH_INT) << arr[i] );
    WriteEndl();
}

void ShowIntValuesBin(int* arr, size_t length) {
    for (size_t i = 0; i < length; ++i) {
        std::bitset<32> bites( arr[i] );
        Write( std::setw(WIDTH_INT) << bites );
    }
    WriteEndl();
}

const int capacity = 256;
int data[capacity];

void Clear() {
    for (size_t i = 0; i < capacity; ++i)
        data[i] = 0;
}

union its {
    char chars[4];
    int value;
} int_to_str;

void FromByteString1(const std::string& buf) {
    int mask[] = {0, 8, 16, 24};
    int validMask = 0xff;
    size_t currentMask = 0, currentIndex = 0;
    for (register size_t i = 0; i < buf.size(); ++i) {
        int tmp = (int) buf[i];
        data[currentIndex] |= ((tmp << mask[currentMask]) & (validMask << mask[currentMask]));
        if (++currentMask == 4) {
            currentMask = 0;
            ++currentIndex;
        }
    }
}

void FromByteString2(const std::string& buf) {
    size_t index = 0;
    for (size_t i = 0; i < buf.size(); i += 4, ++index) {

        int_to_str.chars[0] = buf[i + 0];
        int_to_str.chars[1] = buf[i + 1];
        int_to_str.chars[2] = buf[i + 2];
        int_to_str.chars[3] = buf[i + 3];

        data[index] = int_to_str.value;
    }
}

int main() {

    Clear();

    //std::string value = "this is some string";
    std::string value = "this str";

    ShowStringChars(value);
    ShowStringCodes(value);
    ShowStringCodesBin(value);

    WriteEndl();
    WriteEndl();
    WriteEndl();

    FromByteString1(value);

    ShowIntValues(data, value.length() / 4);
    ShowIntValuesBin(data, value.length() / 4);

    return 0;
}

有没有人有类似的问题?感谢您的帮助:))

1 个答案:

答案 0 :(得分:1)

bitset的流媒体运算符使用std::bitset::to_string,其行为如下:

  

结果字符串包含N个字符,第一个字符对应于最后一个(第N-1)位,最后一个字符对应第一个字符。

因此,输出的最后一个(最右边)字符是最不重要(第一个)位。

您阅读的第一个字节,您移动的最少。因此它成为最不重要的字节。因此,读入整数的第一个字节将是bitset输出中最右边的字节。

解决方案:颠倒读取字节的顺序,即将输入缓冲区解释为小端,而不是大端。

请注意,由于bitset首先打印最高位,因此可以将输出解释为带有单个字节反转的小端,或者将整个集反转的大端。我在这里使用了与从左到右增长的记忆位置相反的反转。

PS。将一个大整数表示为空终止字符串并不是很有用,因为无法表示包含值为零的字节的数字。