#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)