Определите, содержит ли файл двоичные данные или данные ASCII.

Я беру файл в качестве входного аргумента, и мне нужно определить, являются ли данные двоичными или нет (ну, я думаю, ASCII или двоичными), аналогично команде «файл» в * nix, но в моем приложении.

Я не уверен, как это сделать, так как когда я читаю данные, я делаю это так:

fread(&rndByte, sizeof(unsigned int), 1, fp);
// reading one unsigned int at a time from file fp

Я думал о проверке, если значение равно ‹ 128 много раз, но не знаю, как это проверить при чтении всего целого числа за раз. Я хотя и зацикливаюсь по 1 байту за раз и проверяю таким образом, но системе, в которой я работаю, не нравятся сдвиги, которые я делаю.

Есть идеи, предложения?


person naydichev    schedule 05.11.2010    source источник
comment
Ваша проверка потерпит неудачу, если в вашем тексте есть какие-либо специальные символы. Кроме того, чтение байт за байтом происходит очень медленно.   -  person EboMike    schedule 05.11.2010
comment
Почему вы читаете unsigned int за раз? Было бы намного проще читать char за раз.   -  person dan04    schedule 05.11.2010
comment
Почему именно вам нужно это сделать?   -  person Jamie Wong    schedule 05.11.2010
comment
это домашнее задание, нам нужно прочитать беззнаковое целое число, а затем выполнить над ним арифметические действия, чтобы определить, как работает программа. к сожалению, я не могу изменить объем данных, которые я читаю, потому что это то, что требуется. Тем не менее, я думаю, что char может работать... но, я думаю, проще сохранить его как unsigned int.   -  person naydichev    schedule 05.11.2010
comment
Как это облегчает?   -  person dan04    schedule 05.11.2010
comment
Потому что он работает в среде, которую я использую. Я пробовал читать char за раз и сдвигать биты, чтобы получить беззнаковое целое число, но у меня было больше проблем с этим, в отличие от этого метода, который уже удовлетворял мои потребности.   -  person naydichev    schedule 05.11.2010
comment
Арифметика, которую вы ищете для удовлетворения (идиотских) требований домашнего задания, - это побитовый и оператор. Предполагая, что ваш unsigned int 32-битный, if (x & 0x80808080) будет проверять старший бит 4 байтов одновременно.   -  person R.. GitHub STOP HELPING ICE    schedule 05.11.2010


Ответы (3)


Я думал проверить, если значение ‹ 128

Наивно полагать, что текст, даже на английском языке, никогда не будет содержать символы, не входящие в базовую латиницу. Программы Microsoft® особенно любят добавлять в текст дефисы и умные кавычки.

Лучшим подходом является поиск управляющих символов ASCII. Текстовый файл, как правило, имеет много разрывов строк (\n и/или \r в зависимости от платформы) и, возможно, несколько табуляции, но почти никогда не содержит других управляющих символов.

person dan04    schedule 05.11.2010
comment
Ввод, который я ожидаю (если ascii), вероятно, будет содержать только несколько базовых символов, которые будут в этом диапазоне. Но символ \n — хорошее предложение, спасибо. - person naydichev; 05.11.2010

Как уже говорили другие (хотя и менее прямо), в 2010 году ограничивать текст до ASCII полностью наоборот. как UTF-8 и объявляя его двоичным при первом сбое.

Как уже говорили другие, вместо того, чтобы снова и снова вызывать fread или fgetc для крошечных единиц, вы должны fread больших кусков (1-4k) за раз в буфер фиксированного размера и запускать свой синтаксический анализатор над этим, считывая новый кусок каждый раз ты достигаешь конца. (И если ваш синтаксический анализатор UTF-8 нелегко перезапустить, может иметь смысл memcpy конец буфера вернуться к началу и перезаполнить всякий раз, когда в буфере остается менее 4 байтов.)

person R.. GitHub STOP HELPING ICE    schedule 05.11.2010

Используйте fread(), чтобы захватить весь буфер размером 1024 байта (или 512, или что-то еще, что вам подходит), а затем сканируйте этот буфер побайтно в поисках чего-то с установленным восьмым битом. Это, вероятно, довольно близко к тому, что делает файл (1), за исключением того, что файл (1) имеет более сложные шаблоны для рассмотрения и, вероятно, не беспокоится о таком большом буфере.

Вы также можете взять исходный код find и узнать, как он работает.

person mu is too short    schedule 05.11.2010