Я использую dsPic33F (16-разрядный микроконтроллер);Как преобразовать массив байтов в массив int?
- Как конвертировать
char[]
вint[]
таких, что каждые два гольцов становится целое число с помощью C++? - и обратная операция?
Я использую dsPic33F (16-разрядный микроконтроллер);Как преобразовать массив байтов в массив int?
char[]
в int[]
таких, что каждые два гольцов становится целое число с помощью C++?int* intArray = new int[sizeOfByteArray];
for (int i=0; i<sizeOfByteArray; ++i)
intArray[i] = byteArray[i];
Или
std::copy(byteArray, byteArray+sizeofByteArray, intArray);
Сначала вам необходимо прояснить проблему. N байтов -> N ints? если это не так. Арифметика указателя была бы лучше индексации. –
Ну, он сказал байт [] в int [], поэтому я принял соответствие 1: 1 (иначе это просто литье). Да, я бы, вероятно, использовал арифметику указателей или просто std :: copy, но если кто-то не знает, как скопировать массив, я не хочу обфускации операции. – Mud
Что делать, если мне нужно получить int каждые 2 байта? –
Я предполагаю, что вы хотите, чтобы объединить пакеты байтов в междунар?
то, что вам нужно сделать, это сдвинуть биты при создании ИНТ
(оки это Java, потому что я не имею мой C++ код здесь)
public static final int byteArrayToInt(byte [] b) {
return (b[0] << 24)
+ ((b[1] & 0xFF) << 16)
+ ((b[2] & 0xFF) << 8)
+ (b[3] & 0xFF);
}
public static final byte[] intToByteArray(int value) {
return new byte[] {
(byte)(value >>> 24),
(byte)(value >>> 16),
(byte)(value >>> 8),
(byte)value};
}
эту логику работает с любыми форматами конверсий, если вы знаете длину ваших переменных.
@ user440336 Я понимаю ваше решение. Мне пришлось бы адаптировать его к 16-битным целым числам –
, выбирая 24, тогда ^^, если вы получите логику, вы можете использовать этот код для преобразования из любого в любой формат.рад, что он помог –
Я предполагаю, что ваш массив символов содержит байты (вместо фактических символов ascii), которые вы хотите преобразовать в 16-разрядные целые числа. Функция ниже будет работать для заказа первого байта MSB. Здесь я использовал unsigned символы для представления байтового ввода (uint8_t).
void BytesToInts(uint8_t *byteArray, uint16_t byteArraySize, int16_t *intArray, uint16_t intArraySize) {
//do some error checking on the input
if (byteArraySize == 0) return;
if (intArraySize != (byteArraySize/2)) return;
//convert each pair of MSB-first bytes into a signed 16-bit integer
for (uint16_t i=0; i<intArraySize; i++)
{
intArray[i] = (int16_t) ((byteArray[i<<1]<<8) | byteArray[(i<<1)+1]);
}
}
Если вам нужны определения целочисленных, вы можете использовать что-то вроде этого:
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned char uint8_t;
'i + = 2' должен быть дешевле, чем так много бит сдвигов; –
Обратите внимание, что автор сказал о ** DSP **, который, как правило, может содержать любое количество бит в char (возможно, 16), поэтому вы должны быть осторожны: используйте макрос CHAR_BIT вместо 8, проверьте, достаточно ли int для хранения двух символов (2 <= SizeOf (INT)). – Vovanium
+1 @ Vovanium Again Он сказал: «Как преобразовать char [] в int [], чтобы каждый два символа стал int с использованием C++« IE два символа будут вписываться в int –
На DSPIC 33F, я сомневаюсь, что вы используете C++. Если вы используете C++, какой компилятор вы используете, и сколько у вас библиотеки времени выполнения? (И где у вас это получилось!)
Если порядок байтов верен, вы можете просто использовать memcpy(), если вам нужна копия, или просто нарисуйте указатель, если вы просто хотите использовать 16-битные номера в буфера и выравнивание в порядке. Если вы управляете буфером, это не является необычным, чтобы использовать союз для такого рода требования на платформе, как это:
union my_buffer {
unsigned char char_buf[128];
int int_buf[64];
};
Доступа через char_buf при работе с символами, доступ через int_buf при работе с Интс.
Если байты необходимо поменять местами, просто реализовать вариант тампоном() и использовать его вместо тетсру(), что-то, как и другие ответы, или какой-то код, как это:
void doit(int16_t* dest, char const* src, size_t word_count)
{
char* const end = (char*) (dest + word_count);
char* p;
for (p = (char*) dest; p != end; src += 2, p += 2) {
p[0] = src[1];
p[1] = src[0];
}
}
Неправильно. Это будет работать на вашем ПК, но не будет на dsPIC. Помните о значении CHAR_BIT! – Vovanium
+1 Я чувствую, что -1 необоснованно Снова «Как преобразовать char [] в int [], чтобы каждый два символа стал int с использованием C++« –
@vovanium: Wrong. dsPIC 30/33 имеет 8 бит на байт, и поэтому CHAR_BIT определяется как 8. Если CHAR_BIT не был 8, тогда даже не было типа int16_t. – janm
Вот скомпилированный и испытанный метод:
#include <stdio.h>
unsigned short ByteToIntArray(
unsigned char inByteArray[],
unsigned short inArraySize,
unsigned short outWordArray[],
unsigned short outArraySize,
unsigned char swapEndian
)
{
if ( (inArraySize/2 > outArraySize)
|| (outArraySize == 0)
|| (inArraySize == 0)
)
{
return -1;
}
unsigned short i;
if (swapEndian == 0)
{
for (i = 0; i < outArraySize; ++i)
{
outWordArray[ i ] = ((unsigned short)inByteArray[ i*2 ] << 8) + inByteArray[ i*2 + 1 ];
}
}
else
{
for (i = 0; i < outArraySize; ++i)
{
outWordArray[ i ] = ((unsigned short)inByteArray[ i*2 + 1 ] << 8) + inByteArray[ i*2 ];
}
}
return i;
}
int main(){
unsigned char ucArray[ 16 ] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
unsigned short usArray[ 8 ];
unsigned short size;
// "/ 2" on the usArray because the sizes are the same in memory
size = ByteToIntArray(ucArray, sizeof(ucArray), usArray, sizeof(usArray)/2, 0);
if(size > 0)
{
printf("Without Endian Swapping:\n");
for(unsigned char i = 0; i < size ; ++i)
{
printf("0x%04X ", usArray[ i ]);
}
printf("\n");
}
if(size > 0)
{
// "/ 2" on the usArray because the sizes are the same in memory
size = ByteToIntArray(ucArray, sizeof(ucArray), usArray, sizeof(usArray)/2, 1);
printf("With Endian Swapping:\n");
for(unsigned char i = 0; i < size ; ++i)
{
printf("0x%04X ", usArray[ i ]);
}
printf("\n");
}
return 0;
}
ByteToIntArray принимает 5 параметров и возвращает размер фактического преобразованного массива, это удобно, если вы передаете в outWordArray что больше, чем фактический преобразованный размер и в то же время служит средством для сбора ошибок.
Простой бит-оператор сдвига и + используется для объединения двух байтов в одно слово.
Я просто использовал printf для проверки процедур, и я знаю, что для использования этого во встроенном оборудовании обычно требуется выделенное пространство кода. И я просто включил обмен Endian, чтобы убедиться, что вы видите, что вам нужно делать в обоих случаях, но это можно легко удалить в вашей реальной реализации.
Существует также много возможностей для оптимизации в режиме ByteToIntArray, но этот способ легко понять.
Протестируйте его на dsPIC раньше. Нет ничего общего между символами ПК и dsPIC, шортами ant ints. – Vovanium
@Vovanium Он редактирует запрос Используя C++ «Как преобразовать char [] в int [], чтобы каждый два символа стал int с использованием C++», но эй так жив. Также помещается -1 перед комментарием, чтобы указать, что это причина для -1 –
На dsPIC 33 с компилятором MPLAB C30, char имеет 8 бит, int - 16 бит, а sizeof (short) == sizeof (int) == 2. – janm
Я не уверен, что ваш байтовый символ или октет. У вас могут быть октеты, уже упакованные по два в 16-битных словах dsPIC, поэтому у вас больше нет возможности их упаковывать.
#include <limits.h>
#include <stddef.h>
#define BYTE_BIT CHAR_BIT /* Number of significant bits in your 'byte' * Read note below */
/* pack routine */
void ipackc(int *packed, const char *unpacked, size_t nints) {
for(; nints>0; nints--, packed++, unpacked += 2) {
*packed = (unpacked[0]<<BYTE_BIT) | (unpacked[1] & ((1<<BYTE_BIT)-1));
}
}
/* unpack routine */
void cunpacki(char *unpacked, const int *packed, size_t nints) {
for(; nints>0; nints--, packed++, unpacked += 2) {
unpacked[0] = *packed>>BYTE_BIT;
unpacked[1] = *packed & ((1<<BYTE_BIT)-1);
}
}
Это код на языке C, но не имеет ничего общего с функциями C++. Он компилируется в режиме C++. Вы можете заменить limits.h и stddef.h на climits и cstddef для более жесткого соответствия C++.
Примечание о выполнении:
((1<<BYTE_BIT)-1)
является битовой маской для N младших битов, где N = BYTE_BIT. Она равна
/--N--\
...011...11 (binary)
+1 за знание компилятора dsPIC –
(распакованный [1] и ((1 << CHAR_BIT) - 1)) все немного бессмысленно; просто объявите его как (или отбрасывайте) неподписанным символом, чтобы избежать расширения знака. – janm
@janm: Если char шире бит CHAR_BYTE, тогда это имеет смысл. Я понимаю, что этот DSP имеет 8-битный символ, но это не общий случай. Причина, которую я написал, я уже объяснил. – Vovanium
Вы хотите просто изменить тип каждого элемента без изменения значения (то есть, для каждого '' i', ByteArray, [I] == INTArray [я] ') или вам нужно переинтерпретировать массив 'byte' как массив' int' (например, 4 последовательных элемента 'byte' → 1' int' element)? –
Я полагаю, вы имеете в виду 'int' to' char'? – wilhelmtell
@ В силиконе. Каждая пара байтов будет преобразована в один int –