Вопрос по c, stdin, io – C чтение (из стандартного ввода) останавливается на 0x1a символ

1

в настоящее время яРеализация преобразования Берроуза-Уилера (и обратного преобразования) для необработанных данных (например, 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);
Код слишком длинный для публикации. В основном яя использую fread () для чтения из стандартного ввода и яЯ делаю это в то время как цикл. Если fread не прочитал 0 байтов, этот цикл продолжает читать. user1745184
Дон»разместить весь код. Просто та часть, которая демонстрирует проблему. Например. удалите весь ваш код преобразования и создайте программу, которая просто читает из стандартного ввода. Raymond Chen
Сообщение отредактировано, код теперь виден. user1745184
Можете ли вы опубликовать код, который демонстрирует эту проблему, пожалуйста? simonc

Ваш Ответ

5   ответов
4

Как и ты'я заметил, тыперечитываю из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, вы нене наткнуться на это различие в режимах.

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

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

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

fopen("file", "rb");
@ user1745184 Что касается fopen и других базовых файловых операций ввода-вывода, то это файловый поток IS-A. Потоки действуют иначе, когда ищут Earlz
Он должен скомпилироваться и работать под Linux ... user1745184
Стандарт также является файлом. @Earlz 'Совет правильный. (на майкрософт "операционные системы", по крайней мере) wildplasser
На Unix "B"Инари флаг молча игнорируется. 0x1a не является специальным символом, даже в stdin. wildplasser
0

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

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

fd = fcntl(STDIN_FILENO, F_DUPFD, 0);

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

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

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

3

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

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

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

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

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

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

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