#c #string
#c #строка
Вопрос:
У меня есть следующий код, и я пытаюсь вернуть строку с двоичным файлом в формате «0000 0000 0000». Это работает, за исключением того, что в конце строки есть дополнительный 0, и я понятия не имею, как это исправить. Таким образом, вместо того, чтобы быть «0000 0000 1100» для представления 12, оно превращается в «0000 0001 1000»
void convert_to_binary (short acc, char *bin){
//char bin[16] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
/* Copies decimal value to temp variable */
short decimal, tempDecimal;
int index = 0;
tempDecimal = acc;
int length = strlen(bin);
for (index=0; index <19;index ){
if ( index % 4 == 0){
bin[index] == ' ';
} else if (tempDecimal!=0){
bin[index] = (tempDecimal % 2) '0';
tempDecimal /= 2;
//index ;
} else {
bin[index] == '0';
}
}
bin[index] = '';
strrev(bin);
} // convert acc to binary str for output
Комментарии:
1. Использовать отладчик?
2. Вам будет легче решить проблему, если вы удалите неиспользуемые переменные (например, length и decimal) и немного отформатируете свой код. Также
bin[index] == '0';
похоже на опечатку.3. что касается;
int length = strlen(bin);
Похоже, что это попытка получить количество символов — это массив, для которого не было установлено какое-либо конкретное значение. Результатом является неопределенное поведение
Ответ №1:
Некоторые подсказки:
bin[index] == '0';
не выводит a0
, потому что вы используете оператор сравнения==
вместо оператора присваивания=
- то же самое относится и к этой строке
bin[index] == ' ';
- используйте и обращайте внимание на предупреждения компилятора, например, с
gcc -Wall -Wextra main.c
предупреждениями компилятора об упомянутых выше пунктах и о неиспользуемых переменных - вы хотите, чтобы каждый 5-й символ был пробелом, а не каждым 4-м, поэтому используйте
index % 5
вместоindex % 4
- Ваше условие цикла таково
index <19
, что на самом деле так и должно бытьindex < 15
, если вы хотите вывести три группы по 4 символа в каждой, вы, вероятно, не хотите, чтобы такая константа была жестко запрограммирована в такой процедуре - незначительный: некоторые реализации библиотеки удобно включают
strrev
, но если целью является написание переносимого C, вы можете его не использовать
Если вы примените вышеуказанные пункты, результатом будет ‘0000 0000 1100’, который вы хотели бы получить.
Альтернатива
В качестве альтернативы вы можете работать слева направо. Поэтому вам не нужно переворачивать строку. Вы также можете проверить, установлен ли бит с помощью операции сдвига битов в сочетании с битовым тестом, подобным этому:
bool n = (acc >> (unsigned)index) amp; 1u;
При битовых операциях рекомендуется работать со значениями без знака. Количество битов для преобразования может быть параметром вашей функции, поэтому подпись может выглядеть следующим образом:
void convert_to_binary(unsigned acc, int bits, char *bin)
Цикл основан на количестве битов, а не на количестве символов, которые нужно записать, так что после каждого 4-го вывода бита выводится дополнительный символ пробела, так что % 4
его можно использовать здесь.
Тогда это будет выглядеть так:
void convert_to_binary(unsigned acc, int bits, char *bin) {
char *ptr = bin;
for(int index = bits - 1; index >= 0; index--) {
bool n = (acc >> (unsigned)index) amp; 1u;
*ptr = n ? '1' : '0';
if(index % 4 == 0)
*ptr = ' ';
}
*ptr = '';
}
Тест
Это несколько тестовых примеров:
int main(void) {
char buf[40] = {0};
convert_to_binary(0xFFFFFFFF, 32, buf);
printf("%sn", buf);
convert_to_binary(0x7FFFFFFF, 32, buf);
printf("%sn", buf);
convert_to_binary(1, 32, buf);
printf("%sn", buf);
convert_to_binary(0, 32, buf);
printf("%sn", buf);
convert_to_binary(12, 32, buf);
printf("%sn", buf);
convert_to_binary(12, 12, buf);
printf("%sn", buf);
return 0;
}
даст следующий результат:
1111 1111 1111 1111 1111 1111 1111 1111
0111 1111 1111 1111 1111 1111 1111 1111
0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1100
0000 0000 1100