2014-05-07 2 views
2

Если мне задан массив символов размером 8, где я знаю, что первые 3 байта являются идентификатором, следующим байтом является сообщение, а последние 3 байта - это значения. Как я могу использовать манипуляции с битами, чтобы извлечь сообщение.Бит Манипуляция по массиву символов в c

Пример: массив символов содержит 9990111 (одно целое по каждой позиции), где 999 - это идентификатор, 0 - сообщение, а 111 - значение.

Любые советы? Благодаря!

+1

Зачем вам нужны манипуляции с битами для извлечения таких данных из массива char [8]? Это требование для так я причина? – pah

+0

Да. Использовать & оператор для выполнения побитового AND –

+0

@threadp Нет, я думал, что могу просто извлечь это конкретное значение, но решил, что смогу дать ему попробовать использовать манипуляции с битами. – user2899246

ответ

0

Ну, если вы хотите битную манипуляции, независимо от того, что здесь не идет:

#include <stdio.h> 
#include <arpa/inet.h> 

int main(void) { 
     char arr[8] = "9997111"; 
     int msg = 0; 

     msg = ((ntohl(*(uint32_t *) arr)) & 0xff) - 48; 

     printf("%d\n", msg); 

     return 0; 
} 

Выход:

7 

Только помните одну вещь ... это не соответствует строгим ступенчатости правила. Но вы можете использовать материал memcpy() для его решения.

Редактировать # 1 (разборе все это, предоставляя соблюдение строгих правил наложения спектров, и сделать вы видите, что это не имеет никакого смысла):

#include <stdio.h> 
#include <string.h> 
#include <stdint.h> 
#include <arpa/inet.h> 

int main(void) { 
     char arr[8] = "9997111"; 
     uint32_t a[2]; 
     unsigned int id = 0, msg = 0, val = 0; 

     memcpy(a, arr, 4); 
     memcpy(&a[1], arr + 4, 4); 

     a[0] = ntohl(a[0]); 
     a[1] = ntohl(a[1]); 

     id = ((((a[0] & 0xff000000) >> 24) - 48) * 100) + ((((a[0] & 0xff0000) >> 16)- 48) * 10) + (((a[0] & 0xff00) >> 8)- 48); 
     msg = (a[0] & 0xff) - 48; 
     val = ((((a[1] & 0xff000000) >> 24) - 48) * 100) + ((((a[1] & 0xff0000) >> 16)- 48) * 10) + (((a[1] & 0xff00) >> 8)- 48); 

     printf("%d\n", id); 
     printf("%d\n", msg); 
     printf("%d\n", val); 

     return 0; 
} 

Выход:

999 
7 
111 
+0

Возможно, было бы лучше, если бы вы написали 48 как «0». Хотя, опять же, это может не иметь такой большой разницы. Я не уверен, что механизм 'ntohl()' является хорошим способом, хотя он работает. –

+0

Использование ntohl() не является элегантным вообще, но в этом случае оно работает в переносном режиме. Сетевой порядок байтов - это big-endian, который является endiannes в результате прямой копии памяти из массива. Это позволит утверждать, что элементы uint32_t [] будут соответствовать контенту системы, выполняющей этот код. Во всяком случае, это было просто для того, чтобы сделать вывод: бит-манипуляция в этом случае не имеет смысла, а sscanf() - это путь. – pah

0

Обычным способом было бы определить структуру с элементами, которые являются битовыми полями и соответствуют сегментированной информации в вашем массиве. (О, перечитывая свой вопрос: массив заполнен { '9', '9',...} ?? Тогда вы просто sscanf значения с надлежащим смещением в массиве

+0

Да, массив содержит {'9', '9 ',' 9 ',' 0 ',' 1 ',' 1 ',' 1 '}, поэтому sscanf - это путь? – user2899246

+0

Да, с чем-то вроде 'sscanf (arr + 3,"% 1d ", & message)' (хотя sscanf немного переборщик для одного символа ... 'sscanf (arr + 4,"% 3d ", & value)' имеет больше смысла). –

4

Дано:.

массив содержит {» 9' , '9', '9', '0', '1', '1', '1'}

Затем вы можете конвертировать с sscanf():

char buffer[8] = { '9', '9', '9', '0', '1', '1', '1', '\0' }; 
//char buffer[] = "9990111"; // More conventional but equivalent notation 
int id; 
int message; 
int value; 

if (sscanf(buffer, "%3d%1d%3d", &id, &message, &value) != 3) 
    …conversion failed…inexplicably in this context… 
assert(id == 999); 
assert(message == 0); 
assert(value == 111); 

Но нет бит-манипуляция ne там.

0

Вы можете используйте Memory Copy для извлечения значений. Вот пример

char *info = malloc(sizeof(int)*3); 
    char *info2 = malloc(sizeof(int)*1); 
    char *info3 = malloc(sizeof(int)*3); 

    memcpy(info,msgTest, 3); 
    memcpy(info2,msgTest+3, 1); 
    memcpy(info3,msgTest+4, 3); 
    printf("%s\n", msgTest); 
    printf("ID is %s\n", info); 
    printf("Code is %s\n", info2); 
    printf("Val is %s\n", info3); 

Допустим, строка msgTest = «0098457

Отпечаток заявление Willl идет следующим образом ..

идентификатор 009 Кодекс 8 Вэл 457

Надеюсь, это поможет, удачи!

Смежные вопросы