2014-12-12 3 views
2

Я пытаюсь «перевести» массив uint8_t [uint8_t lets_try [16]] в строку из 16 * 8 + 1 [нулевой символ] элементов. Например:преобразование uint8_t в строку [C]

lets_try[0] = 10101010 
lets_try[1] = 01010101 

...

, и я хотел бы иметь строку типа:

1010101001010101 ... [\ 0]

Вот вопросы: 1) есть быстрый способ выполнить эту операцию?

Я пытался сделать это самостоятельно; моя идея начиналась с перевода одной переменной uint8_t в строку и получения полного массива с циклом [я еще не сделал эту последнюю часть]. В конце концов, я написал этот код:

int main() 
{ 
    uint8_t example = 0x14; 
    uint8_t *pointer; 
    char *final_string; 

    pointer = &example; 

    final_string = convert(pointer); 
    puts(final_string); 

    return(0); 
} 


char *convert (uint8_t *a) 
{ 
    int buffer1[9]; 
    char buffer2[9]; 
    int i; 
    char *buffer_pointer; 

    buffer1[8]='\0'; 

    for(i=0; i<=7; i++) 
     buffer1[7-i]=(((*a)>>i)&(0x01)); 

    for(i=0; i<=7; i++) 
     buffer2[i] = buffer1[i] + '0'; 

    buffer2[8] = '\0'; 

    puts(buffer2); 

    buffer_pointer = buffer2; 

    return buffer_pointer; 
} 

Здесь другие несколько вопросов:

2) Я не уверен, что я полностью понимаю волшебство в этом выражении я нашел на сайте: Буфер2 [я] = buffer1 [i] + '0'; может ли кто-нибудь объяснить мне, почему следующие puts (buffer2) не будут работать правильно без + '0'? это нулевой символ в конце новорожденной строки, который заставляет puts() работать? [потому что с нулевым символом он знает, что он печатает настоящую строку?]

3) в коде выше puts (buffer2) дает правильный вывод, в то время как puts в main() ничего не дает; Я схожу с ума, снова и снова просматривая код, я не могу найти, что не так с этим

4) в моем решении Мне удалось преобразовать uint8_t в строку, проходящую из массива int: uint8_t- > int array-> string; есть ли способ сократить эту процедуру, переходя непосредственно из uint8_t в строку или улучшить ее? [В форумах я нашел только решения в C++] он работает, но я нахожу это немного тяжелым и не очень элегантный

Спасибо всем за поддержку

+0

функция 'convert' вызывает неопределенное поведение, потому что она возвращает локальный массив. Вы должны использовать 'malloc'. – mch

+0

Мне непонятно, что вы не понимаете ... первый цикл сдвигает биты байта один за раз, но заполняет буфер 1 цифрами 0 или 1. Добавляя '0' (это число 48 - значение ASCII символа 0) преобразует их в текст. Добавление '\ 0' (целое число 0) в конец завершает строку, поэтому puts() будет знать, где остановиться. –

+1

Не '01010101' буква восьмого числа, а' 10101010' - десятичный номер литерала? –

ответ

3

1.) это немного быстрее, чтобы устранить целочисленный массив.

2.) добавление '0' изменяет целые значения 0 и 1 к их ASCii значений '0' и '1'.

3.) Неопределенное поведение, чтобы вернуть адрес локальной переменной. Вы должны хранить память в куче.

4.) да, просто вырезать его и сделать всю операцию все в один

#include <stdio.h> 
#include <stdlib.h> 

typedef unsigned char uint8_t; 

char *convert(uint8_t *a) 
{ 
    char* buffer2; 
    int i; 

    buffer2 = malloc(9); 
    if (!buffer2) 
    return NULL; 

    buffer2[8] = 0; 
    for (i = 0; i <= 7; i++) 
    buffer2[7 - i] = (((*a) >> i) & (0x01)) + '0'; 

    puts(buffer2); 

    return buffer2; 
} 


int main() 
{ 
    uint8_t example = 0x14; 
    char *final_string; 

    final_string = convert(&example); 
    if (final_string) 
    { 
    puts(final_string); 

    free(final_string); 
    } 
    return 0; 
} 
0

Вот так ...

char *uint8tob(uint8_t value) { 
    static uint8_t base = 2; 
    static char buffer[8] = {0}; 

    int i = 8; 
    for(; i ; --i, value /= base) { 
    buffer[i] = "01"[value % base]; 
    } 

    return &buffer[i+1]; 
} 

char *convert_bytes_to_binary_string(uint8_t *bytes, size_t count) { 
    if (count < 1) { 
    return NULL; 
    } 

    size_t buffer_size = 8 * count + 1; 
    char *buffer = calloc(1, buffer_size); 
    if (buffer == NULL) { 
    return NULL; 
    } 

    char *output = buffer; 
    for (int i = 0 ; i < count ; i++) { 
    memcpy(output, uint8tob(bytes[i]), 8); 
    output += 8; 
    } 

    return buffer; 
}; 

int main(int argc, const char * argv[]) { 
    uint8_t bytes[4] = { 0b10000000, 0b11110000, 0b00001111, 0b11110001 }; 

    char *string = convert_bytes_to_binary_string(bytes, 4); 
    if (string == NULL) { 
    printf("Ooops!\n"); 
    } else { 
    printf("Result: %s\n", string); 
    free(string); 
    } 

    return 0; 
} 

... просто продлить на 16 байт. Есть много способов, и это также зависит от того, что вы имеете в виду с быстро. Встроенные системы, ...? Вы можете сделать таблицу переводов, чтобы сделать ее еще быстрее, ...

UPDATE

char *convert_bytes_to_binary_string(uint8_t *bytes, size_t count) { 
    if (count < 1) { 
    return NULL; 
    } 

    const char *table[] = { 
    "0000", "0001", "0010", "0011", 
    "0100", "0101", "0110", "0111", 
    "1000", "1001", "1010", "1011", 
    "1100", "1101", "1110", "1111" 
    }; 

    size_t buffer_size = 8 * count + 1; 
    char *buffer = malloc(buffer_size); 
    if (buffer == NULL) { 
    return NULL; 
    } 

    char *output = buffer; 
    for (int i = 0 ; i < count ; i++) { 
    memcpy(output, table[ bytes[i] >> 4 ], 4); 
    output += 4; 
    memcpy(output, table[ bytes[i] & 0x0F ], 4); 
    output += 4; 
    } 

    *output = 0; 

    return buffer; 
}; 

int main(int argc, const char * argv[]) { 
    uint8_t bytes[4] = { 0b10000000, 0b11110000, 0b00001111, 0b11110001 }; 

    char *string = convert_bytes_to_binary_string(bytes, 4); 
    if (string == NULL) { 
    printf("Ooops!\n"); 
    } else { 
    printf("Result: %s\n", string); 
    free(string); 
    } 

    return 0; 
} 
+0

@mch: ваш код настолько ясен, ничего себе! большое спасибо за то, что уделили время улучшению моего кода, начиная с моей философии/решения; robert: быстрый означает без промежуточного шага; ваше решение является про-я, я буду внимательно изучать его, потому что он кажется чрезвычайно масштабируемым и да, я работаю над встроенными системами;) lee: мой вопрос касался значения добавления «0». Я все еще сомневался в возвращении ошибки локальных переменных и почему malloc решает все это, но я смотрю на полезные: http://stackoverflow.com/questions/12380758/c-error-function-returns-address-of -local-variable ciao! – Antonino

+0

См. Мой обновленный ответ ... Я оптимизировал его для встроенных систем. Там есть таблица преобразования, также заменил calloc на malloc, нет необходимости в нулевой памяти, все байты будут заменены в любом случае, также нет ссылки на локальный буфер, только один malloc, ... – robertvojta

+0

еще раз спасибо @robert, еще один красивый кусок код ... есть хороший день! – Antonino

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