C чтение (из стандартного ввода) останавливается на 0x1a символ

в настоящее время яРеализация преобразования Берроуза-Уилера (и обратного преобразования) для необработанных данных (например, JPG и т. д.). При тестировании на обычных данных, таких как текстовые файлы, никаких проблем не возникает. Но когда дело доходит до чтения файлов JPG, например. останавливается чтение символа 0x1a, также известного как замещающий символ. Я'искал в интернете решения, которые нея не могу получить зависимый от ОС код, но без результатов ... Я думал читать в стандартном режиме в двоичном режиме, но это не такЯ думаю, это довольно легко. Есть ли простой способ решить эту проблему?

код:

buffer = (unsigned char*) calloc(block_size+1,sizeof(unsigned char));
length = fread((unsigned char*) buffer, 1, block_size, stdin);
if(length == 0){
    // file is empty
}else{
    b_length = length;
    while(length == b_length){
        buffer[block_size] = '\0';
        encodeBlock(buffer,length);
        length = fread((unsigned char*) buffer, 1, block_size, stdin);      
    }
    if(length != 0){            
        buffer[length] = '\0';
        encodeBlock(buffer,length);
    }
}
free(buffer);
 Raymond Chen17 окт. 2012 г., 22:17
Дон»разместить весь код. Просто та часть, которая демонстрирует проблему. Например. удалите весь ваш код преобразования и создайте программу, которая просто читает из стандартного ввода.
 user174518417 окт. 2012 г., 22:15
Код слишком длинный для публикации. В основном яя использую fread () для чтения из стандартного ввода и яЯ делаю это в то время как цикл. Если fread не прочитал 0 байтов, этот цикл продолжает читать.
 simonc17 окт. 2012 г., 22:10
Можете ли вы опубликовать код, который демонстрирует эту проблему, пожалуйста?
 user174518417 окт. 2012 г., 22:24
Сообщение отредактировано, код теперь виден.

Ответы на вопрос(5)

Вы должны открыть файл как двоичный файл.

Используйте что-то похожее на

fopen("file", "rb");
 user174518417 окт. 2012 г., 22:13
Я читаю стандартный ввод, а не файл.
 wildplasser17 окт. 2012 г., 22:21
Стандарт также является файлом. @Earlz 'Совет правильный. (на майкрософт "операционные системы", по крайней мере)
 wildplasser17 окт. 2012 г., 22:26
На Unix "B"Инари флаг молча игнорируется. 0x1a не является специальным символом, даже в stdin.
 user174518417 окт. 2012 г., 22:38
И, насколько я знаю, stdin - это не файл ... Между потоком и файлом все еще есть разница.
 wildplasser18 окт. 2012 г., 02:35
@ user1745184: слова "ФАЙЛ" а также "поток" сильно перегружены. Старый юникс-адагиум "все файл " относится ко всему физическому уровню: иноды и тому подобное. Структура FILE представляет собой обертку вокруг открытого файлового дескриптора, который является указателем на системную таблицу файлов, которая является "открыл» инод. Файлы / inode могут иметь некоторые свойства, такие как is-seekable, is-mmappable или is-selectable. (но stdin все еще ФАЙЛ *) Слово "поток" еще хуже: это может относиться к обработчикам протоколов (sys-V) или специальным типам FILE 'с (с ++). Семантика зависит от области, в которой используется термин.
 Earlz17 окт. 2012 г., 23:11
@ user1745184 Что касается fopen и других базовых файловых операций ввода-вывода, то это файловый поток IS-A. Потоки действуют иначе, когда ищут
 user174518417 окт. 2012 г., 22:25
Он должен скомпилироваться и работать под Linux ...
 user174518418 окт. 2012 г., 00:58
@Earlz Не совсем. Разница между файлом и потоком заключается в том, что поток представляет собой поток между двумя направлениями (например, с диска в память). Файл, скорее всего, представляет собой что-то, что хранится на диске, например, Но вы можете назначить поток (например, stdin) так называемому указателю FILE, который фактически представляет информацию о файле / потоке. Так вообще потокпотоки» out / in данные из / в файл. В этом случае поток НЕ является файлом.

Как и ты'я заметил, тыперечитываю изstdin в режиме ASCII, и он ударяет символ SUB (заменить, иначеCTRL + Z, также известный как DOS End-of-File).

Вы должны изменить режим на двоичный сsetmode в то время как на Windows:

#if defined(WIN32)
#include 
#include 
#endif /* defined(WIN32) */

/* ... */

#if defined(WIN32)
_setmode(_fileno(stdin), _O_BINARY);
#endif /* defined(WIN32) */

На платформах, отличных от Windows, вы нене наткнуться на это различие в режимах.

 eleijonmarck15 дек. 2014 г., 15:45
У меня точно такая же проблема, как и у ОП. Входной файл имеет "^ Z» но когда я пытаюсь заставить stdin читать двоичный файл. Это все еще добирается до eof. Я пытался установить режим, но он просто не работает. Можешь помочь? Может быть, я опубликую новый вопрос.
 eleijonmarck29 янв. 2015 г., 15:12
Привет всем, хотел указать, что _setmode (_fileno (stdin), _O_BINARY); должен быть перед всем остальным в функции main ().

использованиеread() читать в данных.

Поскольку вы заинтересованы в получении данных отstdinиспользовать

fd = fcntl(STDIN_FILENO, F_DUPFD, 0);

чтобы получитьfd изstdin

Больше информацииВот.

Эта проблема связана с тем, чтоокна лечит0x1a а.к.а.CTRL + Z какEOF, Как отметил Эрлз, открытие в двоичном режиме исправляет это в Windows и работает и в Linux.

Ты можешь использовать_setmode конвертировать стандартный ввод в двоичный режим.

Существует такжеfreopen -- увидетьэтот ТАК вопрос

Вы не можете сделать это без зависимости от ОС. Спецификация языка C гласит (7.19.3)

При запуске программы три текстовых потока предопределены ...

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

 user174518417 окт. 2012 г., 22:46
Ну, я надеялся, что найду решение без какого-либо кода для конкретной ОС. Но он должен работать на ОС Linux, но ям на данный момент отлаживаю на windows. Так как мне решить эту проблему на ОС Linux?

Ваш ответ на вопрос