C двоичный файл чтения stdin

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

Мне понравилось, как Delphi хранит строки. Я считаю, что он поддерживает длину / максимальную длину перед строкой (переменной длины). Таким образом, строки могут заканчиваться нулем для совместимости.

Мои проблемы с вашим механизмом: - дополнительный указатель - неизменность si в основных частях вашего языка; обычно строковые типы не являются неизменяемыми, поэтому, если вы когда-нибудь пересмотрите их, это будет сложно. Вам необходимо реализовать механизм «создания копии при изменении» - использование malloc (вряд ли эффективно, но может быть включено сюда просто для удобства?)

Удачи; Написание собственного интерпретатора может быть очень познавательным в понимании в основном грамматики и синтаксиса языков программирования! (по крайней мере, это для меня)

20
задан James Ko 6 September 2016 в 00:11
поделиться

6 ответов

У меня все было правильно с первого раза, за исключением того, что мне нужно было ntohl ... Конверсия в C: бит за битом

-2
ответ дан 30 November 2019 в 00:01
поделиться

fgets () здесь не так. Он нацелен на удобочитаемый текст ASCII, заканчивающийся символами конца строки, а не двоичными данными, и не даст вам того, что вам нужно.

Недавно я сделал именно то, что вы хотите, используя read () звоните. Если ваша программа явно не закрыла stdin, для первого аргумента (дескриптора файла) вы можете использовать постоянное значение 0 для stdin. Или, если вы используете систему POSIX (Linux, Mac OS X или какой-либо другой современный вариант Unix), вы можете использовать STDIN_FILENO.

1
ответ дан 30 November 2019 в 00:01
поделиться

I don't know what OS you are running, but you typically cannot "open stdin in binary". You can try things like

int fd = fdreopen (fileno (stdin), outfname, O_RDONLY | OPEN_O_BINARY);

to try to force it. Then use

uint32_t opcode;
read(fd, &opcode, sizeof (opcode));

But I have no actually tried it myself. :)

0
ответ дан 30 November 2019 в 00:01
поделиться

fread () лучше всего подходит для чтения двоичных данных.

Да, массив символов в порядке, если вы планируете обрабатывать их побайтно.

-1
ответ дан 30 November 2019 в 00:01
поделиться

Что вам нужно, так это freopen () . Из справочной страницы:

Если filename является нулевым указателем, функция freopen () должна попытаться изменить режим потока на тот, который указан в mode, как если бы было использовано имя файла, связанного с потоком в данный момент. В этом случае дескриптор файла, связанный с потоком, не нужно закрывать, если вызов freopen () завершается успешно. Это определяется реализацией, какие изменения режима разрешены (если таковые имеются) и при каких обстоятельствах.

По сути, лучшее, что вы действительно можете сделать, это:

freopen(NULL, "rb", stdin);

Это снова откроет stdin , чтобы быть тот же входной поток, но в двоичном режиме. В обычном режиме чтение из stdin в Windows преобразует \ r \ n (новая строка Windows) в односимвольный ASCII 10. Использование «rb» Режим отключает это преобразование, чтобы вы могли правильно читать двоичные данные.

freopen () возвращает дескриптор файла, но это предыдущее значение (до того, как мы переведем его в двоичный режим), поэтому не используйте это ни за что. После этого используйте fread () , как было упомянуто.

Что касается ваших проблем, однако, вы можете читать не «32 бита», но если вы используете fread () вы будете читать за 4 char s (это лучшее, что вы можете сделать на C - char гарантированно будет как минимум ] 8 бит, но некоторые исторические и встроенные платформы имеют 16 бит char s (некоторые даже имеют 18 или хуже)). Если вы используете fgets () , вы никогда не прочитаете 4 байта. Вы прочитаете как минимум 3 (в зависимости от того, является ли какой-либо из них символом новой строки), а четвертым байтом будет '\ 0' , потому что строки C завершаются нулем, а fgets () завершает чтение нулем (как хорошая функция). Очевидно, это не то, что вам нужно, поэтому вам следует использовать fread () .

22
ответ дан 30 November 2019 в 00:01
поделиться

Рассмотрите возможность использования макроса SET_BINARY_MODE и setmode :

#ifdef _WIN32
# include <io.h>
# include <fcntl.h>
# define SET_BINARY_MODE(handle) setmode(handle, O_BINARY)
#else
# define SET_BINARY_MODE(handle) ((void)0)
#endif

Подробнее о макросе SET_BINARY_MODE здесь: " Обработка двоичные файлы через стандартный ввод-вывод "

Подробнее о setmode здесь: " _ setmode "

17
ответ дан 30 November 2019 в 00:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: