Чтение ifstream в char * для преобразования как int, так и string - PullRequest
0 голосов
/ 16 октября 2019

У меня возникли проблемы с анализом файла двоичных данных со следующим, который читает первую строку

int LineLength = 300;
int Offset= 4586;
ifstream ifn("BinaryFile.bin");
char* line = new char[LineLength];
ifn.seekg(Offset);
while (ifn.good())
{
    ifn.read(line, LineLength);
}   
for (int i = 0; i < LineLength; i++)
    printf("%02X ", line[i]);

Это выводится на печать:

00 FFFFFFDD 01 00 00 22 FFFFFFB0 01 00 03 4F 50 2D 31 01 31 32 33 

Когда я использую шестнадцатеричный редакторчтобы увидеть исходные данные, это выглядит так:

00 55 24 00 00 F4 BC 01 00 03 4F 50 2D 31 01 31 32 33

Я действительно не хочу, чтобы это изменило данные, мне нужно преобразовать некоторые байты в целые числа, а некоторые в строки, а некоторыев конечном итоге, как даты, но у меня есть некоторые реальные проблемы.

string* DataType= new string[3]{ "int","int","string" };
int*  StartingPosition =new int[3] { 1,10,11 };
int*  ColumnWidth =new int[3] { 4,1,25 };       
char* locale = setlocale(LC_ALL, "UTF-8");

for (string Name : DataType) {
    std::vector<char> CurrentColumnBytes(ColumnWidth);
    for (int C = StartingPosition; C < ColumnWidth + StartingPosition; ++C)
    {
        int Index = C - StartingPosition;       
        CurrentColumnBytes[Index] = line[C];
    }
    if (DataType == "int") {
        // still working out how to get a little endian result from 2-4 bytes if I use char
        // since it is combining bytes as shown above
    }
    if (DataType == "string") {
        for (std::vector<char>::const_iterator i = CurrentColumnBytes.begin(); i != CurrentColumnBytes.end(); ++i)
            std::cout << *i;
    }
}

Я попытался использовать wchar_t и wint_t вместо char в качестве типа. С wint_t я смог преобразовать несколько байтов в порядковый номер с прямым порядком байтов, но тогда я не могу вывести из него строку.

Для чего бы это ни стоило, я также попытался использовать следующее, где я смог получить целые числа, но не строки.

int LineLength = 300;
int counter = 0;
wchar_t* line = new wchar_t[LineLength];
while ((c = fgetwc("BinaryFile.bin")) != WEOF) {
    line[counter] = c;
    counter++;
    if (counter > LineLength - 1) {
        break;
    }
}

1 Ответ

0 голосов
/ 16 октября 2019

Хорошо, проблема в том, что вам нужно прочитать файл в массив unsigned char vector /. Также не используйте fgetwc, иначе вы получите только каждый второй байт, И он обнаруживает, когда в строке несколько нулевых байтов, и объединяет их, что может уменьшить ваш счет. Ifstream, похоже, не было простого способа считывания только части файла в unsigned char vector

int LineLength = 300;
int counter = 0;
std::vector<unsigned char> line(LineLength);
while ((c = fgetw("BinaryFile.bin")) != WEOF) {
    line[counter] = static_cast<unsigned char>(c);
    counter++;
    if (counter > LineLength - 1) {
        break;
    }
}

Затем, когда у вас есть это в векторе, вы можете обрабатывать данные отдельно

for (string Name : DataType) { // here just looping over the columns that were defined in the JSON file - excluding some things that aren't relevant
{
    char* locale = setlocale(LC_ALL, "UTF-8");
    std::vector<unsigned char> CurrentColumnBytes(ColumnWidth);     
    for (int C = StartingPosition; C < ColumnWidth + StartingPosition; ++C)
    {
        int Index = C - StartingPosition;       
        CurrentColumnBytes[Index] = BufferedLine[C];
    }
    if (DataType == "int") {    
        cout << DataParser::LEByte(CurrentColumnBytes); //custom function that tests length, converts to Little Endian int from the individual bytes.
    }
    if (DataType == "string") {
        for (int i = 0; i < ColumnWidth; i++)
            cout<<CurrentColumnBytes[i];
    }
    cout<<" | ";    
}
...