Преобразование uint8_t в двоичный файл - PullRequest
1 голос
/ 01 октября 2019

В классе мы учимся создавать файлы ppm6. У нас есть двумерный массив uint8_t, и класс просит нас использовать fwrite(), чтобы каким-то образом преобразовать этот двумерный массив в набор двоичных символов, которые выглядят следующим образом:

ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿ

Как это сделатьоб этом?

Кто-то в классе говорит, что он автоматически сделает конвертацию, что для меня вообще не имеет смысла. Это то, что я сейчас возвращаю. color_array - это двумерный массив uint8_t, и каждый color_array[i] дает массив из трех uint8_t с.

fwrite(color_array[i], sizeof(uint8_t), 3, output);

И мой вывод:

???????????????????

1 Ответ

2 голосов
/ 01 октября 2019

Прежде всего, некоторые основы.

Запись данных «в двоичной форме» не означает ничего особенного. Программа просто берет все, что имеет в оперативной памяти, и записывает его в файл. Это означает, что что-то вроде этого:

uint8_t x = 10;
fwrite(&x, sizeof(uint8_t), 1, some_file);

приведет к двоичному значению 10, непосредственно записанному в открытый some_file. Поскольку значение 10 хранится в uint_8, а sizeof(uint_8) равно 1 (один байт), в результате этого вызова будет записан ровно один байт. Двоичное представление (в виде одного байта) 10 равно 00001010.

Если после записи двоичного файла вы попытаетесь открыть его с помощью текстового редактора или попытаетесь распечатать его на терминале с помощью чего-то вроде cat, он будет интерпретирован как текст на основе кодировки , настроенной в текстовом редакторе или терминале. Это, скорее всего, приведет к случайным и странным буквам, потому что эти двоичные данные просто не предназначены для представления некоторого текста, а представляют собой целочисленные значения одного байта. Это может знать только тот, кто создал файл. Сами двоичные данные могут иметь бесконечные интерпретации.


С учетом сказанного вы видите там:

ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ

Это именно то, что я описал. Чтобы увидеть значения real , вы должны передать эти выходные данные в шестнадцатеричный просмотрщик, например, команду hd:

$ hd your_file
00000000  c3 bf 00 00 c3 bf 00 00  c3 bf 00 00 c3 bf 00 00  |................|                                                                        
00000010  c3 bf                                             |..|                                                                                     
00000012         

Если этот текст отображался с использованием UTF-8 (наиболее вероятно) записанные байты - это те, которые показаны выше и которые преобразованы из шестнадцатеричного в десятичное:

195 191 0 0 195 191 0 0 195 191 0 0 195 191 0 0 195 191

Теперь поговорим о реальном коде, который вы разместили:

То, что вы делаете, правильно, если предположить, что ваш 2D-массив равен Nx3. Чтобы записать двоичные данные в файл, fwrite() является правильной функцией.

Итак, это:

fwrite(color_array[i], sizeof(uint8_t), 3, output);

Записывает i-ую строку двумерного массива, который состоит из3 uint8_t значений в файл в двоичном виде.

В качестве примера рассмотрим следующее:

uint8_t color_array[2][3] = {{1, 2, 3}, {10, 11, 12}};

fwrite(color_array[0], sizeof(uint8_t), 3, output);
fwrite(color_array[1], sizeof(uint8_t), 3, output);

В результате вы получите файл, который выглядит следующим образом:

$ hd your_file
00000000  01 02 03 0a 0b 0c                                 |......|                                                                                  
00000006 
...