Преобразование десятичного массива в массив двоичных строк с помощью calloc
Я пропустил часть кода, но в основном у меня есть массив десятичных дробей, и я пытаюсь преобразовать его в двоичные числа, но в виде массива строк. Совершенно новый для C и действительно цепляющийся за соломинку в данный момент. Я очень не уверен в том, как используются malloc и calloc. Это моя попытка просто заставить его работать для первой числовой / двоичной строки:
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
void binstringconvert (unsigned long int *decimals, char **binarystrings);
int main (int argc, char **argv)
{
// initialize variables
int numLines = 9;
int binaryLength = 32;
unsigned long int decimals[numLines];
decimals[0] = 3241580200;
// convert decimal array to 32-bit binary string array
char **binarystrings = calloc (numLines, binaryLength);
binstringconvert(decimals, binarystrings);
// test print
printf("\n\n%lu in binary number system is: ", decimals[0]);
printf("\n%s", binarystrings[0]);
}
void binstringconvert (unsigned long int *decimals, char **binarystrings)
{
int c, k;
for (c = 31; c >= 0; c--)
{
k = decimals[0] >> c;
if (k & 1)
binarystrings[0][c] = '1';
else
binarystrings[0][c] = '0';
}
}
Я инициализировал binarystrings
должным образом? Могу ли я писать отдельным персонажам так, как я пытался? На данный момент это дает мне ошибку.
2 ответа
Я прошу прощения, я интерпретировал, что вы хотели передать несколько функций в вашу функцию, чтобы они все были преобразованы в двоичные строки и возвращены. Неважно, пример все еще работает. В любом случае, чтобы вставить 32-битное число в строку, вам понадобится 33 символа (+1 для символа, заканчивающегося нулем). Кроме того, вы пишете свою двоичную строку в обратном порядке.
Всего несколько твиков исправят порядок. Пример:
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
enum { DWRD = 32 };
void binstringconvert (unsigned *decimals, char (*binarystrings)[DWRD+1], int n);
int main (void)
{
/* initialize variables */
unsigned int decimals[] = { 1, 255, 65535, 8388607,
3241580200, 2898560974,
4294967295, 3097295382,
1076482445, 1234567890 };
char (*binarystrings)[DWRD+1] = {NULL};
int i, n = sizeof decimals/sizeof *decimals;
binarystrings = calloc (n, sizeof *binarystrings);
binstringconvert (decimals, binarystrings, n);
/* test print */
for (i = 0; i < n; i++)
printf (" %10u : %s\n", decimals[i], binarystrings[i]);
free (binarystrings);
return 0;
}
void binstringconvert (unsigned *decimals, char (*binarystrings)[DWRD+1], int n)
{
int c, i, k;
for (i = 0; i < n; i++) {
for (c = 31; c >= 0; c--)
{
k = decimals[i] >> c;
if (k & 1)
binarystrings[i][31-c] = '1';
else
binarystrings[i][31-c] = '0';
}
binarystrings[i][DWRD] = 0; /* nul-terminate */
}
}
Выход
$ ./bin/binstrings
1 : 00000000000000000000000000000001
255 : 00000000000000000000000011111111
65535 : 00000000000000001111111111111111
8388607 : 00000000011111111111111111111111
3241580200 : 11000001001101101001011010101000
2898560974 : 10101100110001001000011111001110
4294967295 : 11111111111111111111111111111111
3097295382 : 10111000100111001111101000010110
1076482445 : 01000000001010011101000110001101
1234567890 : 01001001100101100000001011010010
Вам нужно выделить место для массива указателей на строки, а также самих строк. Первый звонок calloc()
выделяет массив указателей на строки и каждый malloc()
выделяет сами строки:
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
void binstringconvert (unsigned long int *decimals, char **binarystrings);
int main (int argc, char **argv)
{
// initialize variables
int numLines = 9;
int binaryLength = 32;
unsigned long int decimals[numLines];
decimals[0] = 3241580200;
int i;
// Allocate an array of numLines pointers to strings
char **binarystrings;
if ( (binarystrings = calloc(numLines, sizeof(*binarystrings))) == NULL )
return EXIT_FAILURE;
// Allocate space for each string
// binaryLength bits plus one for null terminator
for ( i=0; i<numLines; ++i ) {
if ( (binarystrings[i] = malloc((binaryLength + 1)*sizeof(**binarystrings))) == NULL )
return EXIT_FAILURE;
}
// convert decimal array to 32-bit binary string array
binstringconvert(decimals, binarystrings);
// test print
printf("\n\n%lu in binary number system is: ", decimals[0]);
printf("\n%s", binarystrings[0]);
}
void binstringconvert (unsigned long int *decimals, char **binarystrings)
{
int c, k;
for (c = 31; c >= 0; c--)
{
k = decimals[0] >> (31 - c);
if (k & 1)
binarystrings[0][c] = '1';
else
binarystrings[0][c] = '0';
}
binarystrings[0][32] = '\0';
}
Кроме того, вы не записали нулевой терминатор в конец строки. При попытке написать это (printf("\n%s", binarystrings[0]);
) он продолжит читать по памяти, мимо того места, где вы хотите, чтобы был конец. Запись нуля ('\0') в конце требует одного дополнительного символа в распределении, следовательно, +1
в malloc()
звонки.
Обратите внимание на использование sizeof()
оператор. Вы никогда не должны жестко кодировать объем памяти. В Си, пусть компилятор выяснит, насколько большие вещи, не пытайтесь угадать. Указатель может быть 4 байта в 32-битной системе и 8 байтов в 64-битной системе. Даже если вы знаете, какая у вас система и насколько она будет большой, используйте sizeof()
,
Редактировать: Исправлена логическая ошибка, замеченная @DavidCRankin:
k = decimals[0] >> (31 - c);