Преобразование строки C в двоичное представление

#c #string #bytearray

#c #строка #массивы

Вопрос:

Как в ANSI C преобразовать строку в массив двоичных байтов? Все поиски в Google дают мне ответы для C и других, а не C.

Одна из моих идей заключалась в том, чтобы преобразовать строку в ASCII, а затем преобразовать каждое значение ASCII в его двоичный код. (Ага!) Я знаю, что это самая глупая из идей, но я не уверен ни в каком другом варианте.

Я слышал о функции кодирования в Java. Я не уверен, подходит ли это для той же цели и может ли быть принято на C.

 string = "Hello"
bytearr[] = 10100101... some byte array..
  

Было бы здорово, если бы кто-нибудь мог пролить некоторый свет на это.

Спасибо!

Комментарии:

1. Что вы подразумеваете под «массивом двоичных байтов»? «Строка» в C — это просто фрагмент памяти (массив), содержащий значения (байты), которые преобразуются в символы ASCII.

2. Что-то похожее на массив байтов в Java. Где u может обрабатывать строку также в виде массива байтов.

3. Похоже, вы сильно запутались в терминологии. Строка в C уже представляет собой массив двоичных байтов, более или менее по определению. И, вероятно, это также уже ASCII (если только это не какая-то другая кодировка Unicode, которая поддерживает символы за пределами U 0000 через U 007F). Поэтому, пожалуйста, попробуйте еще раз объяснить, каким вы хотите видеть содержимое этого «bytearr».

Ответ №1:

Или вы имели в виду, как преобразовать строку C в двоичное представление?

Вот одно из решений, которое может преобразовывать строки в двоичное представление. Это можно легко изменить, чтобы сохранить двоичные строки в виде массива строк.

 #include <stdio.h>

int main(int argc, char *argv[])
{
    if(argv[1] == NULL) return 0; /* no input string */

    char *ptr = argv[1];
    int i;

    for(; *ptr != 0;   ptr)
    {
        printf("%c => ", *ptr);

        /* perform bitwise AND for every bit of the character */
        for(i = 7; i >= 0; --i) 
            (*ptr amp; 1 << i) ? putchar('1') : putchar('0');

        putchar('n');
    }

    return 0;
}
  

Пример ввода и вывода:

./ascii2bin hello

 h => 01101000
e => 01100101
l => 01101100
l => 01101100
o => 01101111
  

Ответ №2:

В C. Нет никаких строк. Любая строка представляет собой массив байтов.

Комментарии:

1. Я имел в виду «Любая строка представляет собой массив байтов».

Ответ №3:

Строка — это массив байтов.

Если вы хотите отобразить значение ASCII каждого символа в шестнадцатеричной форме, вам просто нужно сделать что-то вроде:

 while (*str != 0)
  printf("x ", (unsigned char) *str  );
  

Ответ №4:

В большинстве систем, над которыми я работал, ширина char равна 1 байту, и поэтому char[] or char* является массивом байтов.

В большинстве других языков, таких как Java, строковый тип данных заботится о том, чтобы в определенной степени учитывать такие понятия, как кодирование, используя кодировку, скажем, UTF-8. В C это не так. Если бы я прочитал строку UTF-8, содержимое которой включало бы многобайтовые значения, мои символы были бы представлены двумя сегментами в массиве (или, возможно, больше).

Чтобы взглянуть на это с другой точки зрения, учтите, что все типы в C имеют фиксированную ширину для вашей системы (хотя они могут различаться в разных реализациях).

Итак, строка, с которой вы работаете, является массивом байтов.

Тогда, я думаю, следующий вопрос заключается в том, как вы отображаете эти байты? Это довольно просто:

 char* x = ???; /* some string */
unsigned int xlen = strlen(x);
int i = 0;

for ( i = 0; i < xlen; i   )
{
    printf("%x", x[i]);
}
  

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

Комментарии:

1. Это не совсем то же самое, что «ширина char равна 1 байту», но, вероятно, это заслуживает повторения в этом контексте: sizeof(char)==1 ПО ОПРЕДЕЛЕНИЮ. Это никогда не будет чем-то другим. (Однако значение CHAR_BIT не обязательно равно 8.)

Ответ №5:

Если вы просто хотите выполнить итерацию (или случайный доступ) числовых значений отдельных байтов, вам вообще не нужно выполнять какое-либо преобразование, потому что строки C уже являются массивами:

 void dumpbytevals(const char *str)
{
    while (*str)
    {
        printf("x ", (unsigned char)*str);
        str  ;
    }
    putchar('n');
}
  

Однако, если вы не будете осторожны с такого рода кодом, вы рискуете попасть в беду, когда вам потребуется поддерживать символы, отличные от ASCII.

Ответ №6:

Поскольку printf работает медленно при преобразовании огромного двоичного массива. Вот еще один подход, который не использует printf:

 #define BASE16VAL               ("x0x1x2x3x4x5x6x7x8x9|||||||xAxBxCxDxExF") 
#define BASE16_ENCODELO(b)      (BASE16SYM[((uint8)(b)) >> 4])
#define BASE16_ENCODEHI(b)      (BASE16SYM[((uint8)(b)) amp; 0xF]) 
#define BASE16_DECODELO(b)      (BASE16VAL[Char_Upper(b) - '0'] << 4)
#define BASE16_DECODEHI(b)      (BASE16VAL[Char_Upper(b) - '0']). 
  

Чтобы преобразовать шестнадцатеричную строку в массив байтов, необходимо выполнить следующее:

 while (*Source != 0)   
    {   
    Target[0]  = BASE16_DECODELO(Souce[0]);   
    Target[0] |= BASE16_DECODEHI(Souce[1]);    

    Target  = 1;   
    Source  = 2;   
    } 

*Target = 0;
  

Источник — это указатель на массив символов, содержащий шестнадцатеричную строку.
Цель — это указатель на массив символов, который будет содержать массив байтов.

Чтобы преобразовать массив байтов в шестнадцатеричную строку, вам необходимо выполнить следующее:

 while (*Source != 0)   
    {   
    Target[0] = BASE16_ENCODELO(*Source);   
    Target[1] = BASE16_ENCODEHI(*Source);    

    Target  = 2;   
    Source  = 1;   
    }
  

Target — это указатель на массив char, содержащий шестнадцатеричную строку.
Источник — это указатель на массив символов, который будет содержать массив байтов.

Вот несколько отсутствующих макросов:

 #define Char_IsLower(C)  ((uint8)(C - 'a') < 26)
#define Char_IsUpper(C)  ((uint8)(C - 'A') < 26)
#define Char_Upper(C)    (Char_IsLower(C) ? (C   ('A' - 'a')) : C)
#define Char_Lower(C)    (Char_IsUpper(C) ? (C   ('a' - 'A')) : C)