Я пытаюсь записать в файл двоичное число 16-битного целого числа со знаком. Я много искал и, конечно же, нашел много примеров преобразования целочисленных переменных в двоичные. Но в моем случае эти функции не будут эффективными, потому что мне нужно преобразовать 50e6 отсчетов / с. Вызов функции для преобразования каждой выборки потребует много вычислительного времени.

Итак, что я хочу сделать, это:

int array[] = {233, 431, 1024, ...}
for (i = 0; i < sizeof(array); i++){
    fprintf(outfile, "%any_binary_format \n", array[i]);
}

Результат в файле должен быть:

0000000011101001
0000000110101111
0000010000000000
-3
Niclas Resse 24 Сен 2018 в 19:15

2 ответа

Лучший ответ

fprintf предназначен для форматированного вывода - форматирование представляет собой "читаемый человеком" текст, поэтому эту функцию нельзя использовать, если вы хотите двоичный вывод. Для этого вы должны использовать fwrite():

for (i = 0; i < sizeof(array) / sizeof(*array); i++ )
{
    fwrite (&array[i], sizeof(*array), 1, outfile ) ;
}

Обратите внимание, что я также исправил завершение цикла, чтобы правильно перебирать количество элементов в массиве. Но на самом деле цикл не нужен - вывод двоичный, массив двоичный - вы можете просто вывести весь массив таким образом:

fwrite( array, sizeof(array), 1, outfile ) ;

Ваши требования к производительности в 50 Мбит / с потребуют постоянной скорости записи около 95 Мбит / с - это очень много, и вряд ли будет достигнуто путем записи одного сэмпла за раз. Возможно, вам будет лучше использовать файл с отображением памяти, но, если вы не используете ОС реального времени, нет никаких гарантий, что вы будете поддерживать эту скорость вывода бесконечно - для доступа к диску требуется только какой-то другой процесс, и он может ввести недопустимая задержка.

Также обратите внимание, что файл должен быть открыт для двоичного вывода - особенно в Windows, чтобы предотвратить преобразование CR в CR + LF, которое будет иметь катастрофические последствия для ваших образцов данных.

1
Clifford 24 Сен 2018 в 17:07

Если вы хотите использовать printf, вы можете использовать что-то вроде этого:

#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c\n"
#define BYTE_TO_BINARY(byte)  \
  (byte & 0x80 ? '1' : '0'), \
  (byte & 0x40 ? '1' : '0'), \
  (byte & 0x20 ? '1' : '0'), \
  (byte & 0x10 ? '1' : '0'), \
  (byte & 0x08 ? '1' : '0'), \
  (byte & 0x04 ? '1' : '0'), \
  (byte & 0x02 ? '1' : '0'), \
  (byte & 0x01 ? '1' : '0')

int main()
{
   uint8_t value = 5;  
   printf(BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(value));
   return 0;
}

Должен напечатать 00000101. Я иногда использую это во встроенном коде при отладке для проверки значений регистров. Просто замените printf на fprintf, если вы хотите записать двоичные строки ascii в файл.

0
Marius 24 Сен 2018 в 16:54