Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Копирование из STDIN в файл, Использование стандартных std-streams 
V
    Опции темы
EvilsInterrupt
Дата 16.10.2011, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Основная задача, которую хочу решить это скопировать из STDIN во внутренний временной файл моей программы. 

Пытаюсь решить ее так:

Код

namespace MyFramework
{
//
// ....
//
void StreamUtils::copyStream( std::istream& input, std::ostream& output )
{
    output.seekp( 0 );

    while( !input.eof() )
    {
        char buffer[ 0x1000 ];

#include <disable_depricated_warning>
        std::streamsize len = input.readsome( buffer, (std::streamsize)sizeof(buffer) );
#include <enable_depricated_warning>

        output.write( buffer, len );
     }
}
//
// ....
//
} // namespace MyFramework


Пользовательский код:
Код

// ...
//
    std::fstream srcTmpfile;
    std::string  srcTmpname = MyFramework::FileUtils::openTmpfile( srcTmpfile, "mcrypt" );
    MyFramework::StreamUtils::copyStream( std::cin, srcTmpfile );


Здесь метод MyFramework::FileUtils::openTmpfile просто берет ссылку на объект fstream и префикс к имени файла,
затем открывает файл и возвращает его имя, к примеру "mcrypt_23A4.tmp"

При использовании в командной строке Windows 7 x64 в таком виде:

Код

Путь к моей программе>\type "test-vector.bin" | myprog.exe 2> err.txt


Я наблюдаю зависание.
Чтобы понять в чем собственно проблема я обрамил "output.write( buffer, len );" выводами
в std::cerr количества прочитанного и записанного в файл. Результат: ноль прочитано и
ноль же записано.

Вот точнее:
Цитата

Last error: No error
Data from STDIN was read with size : 0
Data to FILE was written with size : 0
Last error: No error
Data from STDIN was read with size : 0
Data to FILE was written with size : 0
Last error: No error



Прошу помочь разобраться где я туплю?


Это сообщение отредактировал(а) EvilsInterrupt - 16.10.2011, 12:22
PM MAIL WWW ICQ Jabber   Вверх
EvilsInterrupt
Дата 16.10.2011, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Более, того, как наиболее красивее решить траблу чтения из stdin в raw режиме ?
PM MAIL WWW ICQ Jabber   Вверх
xvr
Дата 17.10.2011, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(EvilsInterrupt @  16.10.2011,  11:13 Найти цитируемый пост)
Результат: ноль прочитано и
ноль же записано.

А еще оно может банально заблокироваться  smile 
У STDIN потока (и равно как и любого другого, прикрепленного не к файлу) может EOF вообще не случиться - ну нету у коммуникационных ресурсов 'концов'  smile 
На уровне ОС можно проверить тип файлового потока, но C++ stream эту информацию не предоставляет, увы  smile 

PM MAIL   Вверх
bsa
Дата 18.10.2011, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(EvilsInterrupt @  16.10.2011,  14:21 Найти цитируемый пост)
Более, того, как наиболее красивее решить траблу чтения из stdin в raw режиме ? 

Цитата(http://msdn.microsoft.com/en-US/library/tw4k6df8(v=VS.80).aspx)
Код
// crt_setmode.c
// This program uses _setmode to change
// stdin from text mode to binary mode.


#include <stdio.h>
#include <fcntl.h>
#include <io.h>

int main( void )
{
   int result;

   // Set "stdin" to have binary mode:
   result = _setmode( _fileno( stdin ), _O_BINARY );
   if( result == -1 )
      perror( "Cannot set mode" );
   else
      printf( "'stdin' successfully changed to binary mode\n" );
}

PM   Вверх
EvilsInterrupt
Дата 18.10.2011, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



bsa, 
Спасибо, а этот код на UNIX-like системе будет работать?
Цитата

The Microsoft run-time library supports American National Standards Institute (ANSI) C and UNIX 


Насколько понял функция относится к runtime-библиотеке и вроде должен...

xvr,
Я правильно понимаю что символы перенаправления такие как '|', '<', '>' должна брать на
себя оболочка. В случае windows это cmd.exe . Все верно?
 Это не программа парсит свою ком.строку...(было бы глупо)
PM MAIL WWW ICQ Jabber   Вверх
fish9370
Дата 18.10.2011, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(xvr @  17.10.2011,  14:09 Найти цитируемый пост)
ну нету у коммуникационных ресурсов 'концов'


- есть, которые как раз и обозначают конец передачи..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
bsa
Дата 18.10.2011, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(EvilsInterrupt @  18.10.2011,  09:15 Найти цитируемый пост)
а этот код на UNIX-like системе будет работать?

Думаю что нет. Просто заключи в #ifdef/#endif. Под *nix нет различия между двоичным и текстовым файлами. Более того, там даже нет O_BINARY. smile

Добавлено через 2 минуты и 42 секунды
Цитата(EvilsInterrupt @  18.10.2011,  09:15 Найти цитируемый пост)
Я правильно понимаю что символы перенаправления такие как '|', '<', '>' должна брать на
себя оболочка. В случае windows это cmd.exe . Все верно?
Да, верно.
PM   Вверх
xvr
Дата 18.10.2011, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(EvilsInterrupt @  18.10.2011,  08:15 Найти цитируемый пост)
Я правильно понимаю что символы перенаправления такие как '|', '<', '>' должна брать на
себя оболочка. В случае windows это cmd.exe . Все верно?

Да

Цитата(fish9370 @  18.10.2011,  09:55 Найти цитируемый пост)
- есть, которые как раз и обозначают конец передачи.. 

Далеко не у всех. Например у COM порта, открытого в бинарном режиме, такого символа нет (даже если из машины физически выдернуть шнур, она этого не почувствует)

PM MAIL   Вверх
EvilsInterrupt
Дата 18.10.2011, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



bsa, 
Цитата

Под *nix нет различия между двоичным и текстовым файлами. Более того, там даже нет O_BINARY.

Кажется ты прав ссылка на исходник
Еще одна ссылка правда уже на Python.

Похоже это стандартное решение. С помощью _setmode() функции

Вопрос как поменять режим std::cin считаю закрытым.

Другую часть темы завтра проведу эксперименты и отпишусь

Это сообщение отредактировал(а) EvilsInterrupt - 18.10.2011, 23:33
PM MAIL WWW ICQ Jabber   Вверх
EvilsInterrupt
Дата 18.10.2011, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



xvr, 
Цитата

Далеко не у всех. Например у COM порта, открытого в бинарном режиме, такого символа нет (даже если из машины физически выдернуть шнур, она этого не почувствует)

Согласен но это есть решение "одна задача - одна программа". Т.е. когда чтото не имеет конца, пусть эту траблу решает другая программа.
PM MAIL WWW ICQ Jabber   Вверх
xvr
Дата 19.10.2011, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(EvilsInterrupt @  18.10.2011,  23:34 Найти цитируемый пост)
Т.е. когда чтото не имеет конца, пусть эту траблу решает другая программа. 

Ну в таком случае чтение 0 байт вполне можно считать синонимом конца файла.

PM MAIL   Вверх
EvilsInterrupt
Дата 20.10.2011, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



В общем-то, полез в Брайна Кернигана. Целью было выяснить ответ на вопрос по символам перенаправления.
Читаю:
Цитата

...важно помнить, что интерпретацию символов <, > осуществляет оболочка(как и интерпретацию символов
типа * в шаблонах имен файлов ), а не конкретные программы.


Пытаюсь провести эксперимент:
Код

type .\bin\Win32-Release\MalwareDetect.map



Отлично работает, но как только:
Код

type < .\bin\Win32-Release\MalwareDetect.map


Наблюдаю:
Цитата

The syntax of the command is incorrect.


Кажется, ком. оболочка Windows более ограничена, чем я думал....

Это сообщение отредактировал(а) EvilsInterrupt - 20.10.2011, 10:24
PM MAIL WWW ICQ Jabber   Вверх
xvr
Дата 20.10.2011, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



type игнорирует входной поток и ожидает 1 параметр. Так что вариант с type < .,,, в принципе ошибочный

PS. Символы * и ? во входной строке cmd.exe в Win не раскрывает, в отличие от Linux

PM MAIL   Вверх
feseal
Дата 24.10.2011, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 18.5.2011

Репутация: нет
Всего: нет



Я не до конца разобрался, что хочет автор.
Какое назначение имеют строки при вызове 
Цитата

type "test-vector.bin"


Если в качестве входного файла используется текстовый формат, то для направления его содержимого в std::cin оболочка использует оператор <, то есть
myprog.exe <test-vector.txt 2> err.txt
Using command redirection operators
Если в качестве входного файла используется двоичный формат, то я бы посоветовал автору передать в программу имя двоичного файла через параметры командной строки, открыть его внутри и сделать копию. Так как для std::cin характерен текстовый ввод.

Хотелось бы немного сказать о копировании в текстовом формате std::cin. Нет смысла писать свою функцию, достаточно воспользоваться алгоритмом std::copy:

Код

std::ofstream out("имя файла результата"); //поток, куда записывать содержимое std::cin
...//тут можно проверить, что файл результата успешно открыт
std::copy( std::istream_iterator<char>(std::cin), std::istream_iterator<char>(), std::ostream_iterator<char>(out)); //собственно копирование


Это сообщение отредактировал(а) feseal - 24.10.2011, 14:12
PM MAIL   Вверх
EvilsInterrupt
Дата 9.11.2011, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Цитата

Я не до конца разобрался, что хочет автор.

Закон разработки прост: Сначала пойми задачу, а потом принимайся за работу!!!
Если ты не понял цели темы, то не берись отвечать никогда!!!

Вобщем эксперименты таковы:

Код

int main( int argc, char* argv[] )
{

#if !defined( unix )
    setmode( fileno( stdin ), O_BINARY );
    setmode( fileno( stdout ), O_BINARY );
#endif

    printf( "\n\nFirst................\n\n" );

    char buffer[0x1000];
    memset( buffer, 0, sizeof(buffer) );
    while( true )
    {
        size_t len = fread( buffer, sizeof(char), sizeof(char) * sizeof(buffer), stdin );
        if( len == 0 )
        {
            break;
        }
        for( size_t i=0; i<len; i++ )
        {
            printf( "0x%.2X ", buffer[i] );
            if( i>0 && i%8 == 0 )
            {
                printf( "\n" );
            }
        }
    }

    std::cout << std::endl << std::endl << "Second................" << std::endl << std::endl;

    memset( buffer, 0, sizeof(buffer) );
    while( !std::cin.eof() && !std::cin.fail() )
    {
        std::streamsize len = std::cin.readsome( buffer, (std::streamsize)sizeof(buffer) );
        if( len == 0 )
        {
            break;
        }
        for( std::streamsize i=0; i<len; i++ )
        {
            std::cout << std::uppercase << std::hex << buffer[8];
            if( i>0 && i%8 == 0 )
            {
                std::cout << std::endl;
            }
        }
    }

    return 0;
}


результат:
Цитата

First................

0xFFFFFF89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A 0x00
0x00 0x00 0x0D 0x49 0x48 0x44 0x52 0x00
0x00 0x00 0x0C 0x00 0x00 0x00 0x0C 0x08
0x00 0x00 0x00 0x00 0x73 0x1E 0x03 0x3B
0x00 0x00 0x00 0x63 0x49 0x44 0x41 0x54
0x78 0xFFFFFFDA 0x55 0xFFFFFF8E 0xFFFFFFB1 0x0D 0xFFFFFFC0 0x30
0x08 0x04 0xFFFFFFBF 0xFFFFFFA4 0xFFFFFFF4 0x1A 0x2E 0x29
0xFFFFFFBD 0x42 0x66 0xFFFFFFA3 0x74 0xFFFFFFE9 0x36 0x23
0x64 0xFFFFFF8D 0xFFFFFFAC 0xFFFFFFC1 0x08 0xFFFFFF94 0x04 0x48
0xFFFFFFA2 0x28 0x14 0xFFFFFFF0 0x27 0xFFFFFFA4 0xFFFFFFFF 0xFFFFFF87
0xFFFFFFBB 0xFFFFFFCD 0xFFFFFFD1 0xFFFFFFDA 0x58 0xFFFFFFE6 0x0E 0x57
0x06 0xFFFFFFA8 0x03 0xFFFFFFAC 0x0E 0x0B 0x0D 0x39
0x63 0xFFFFFFB1 0x41 0xFFFFFF80 0x4D 0x2D 0x21 0x64
0x3E 0xFFFFFFB0 0x17 0x30 0x28 0xFFFFFFCF 0x2A 0xFFFFFFA0
0x3F 0xFFFFFFF0 0x07 0xFFFFFF9C 0x06 0x2F 0xFFFFFFC8 0x63
0x7D 0xFFFFFFDC 0xFFFFFFD6 0xFFFFFFAE 0x1D 0x35 0x19 0x1A
0x75 0xFFFFFF84 0xFFFFFF89 0xFFFFFFC6 0xFFFFFF8C 0x3A 0x17 0xFFFFFFC0
0x78 0x2C 0x16 0xFFFFFFEC 0xFFFFFFC1 0x54 0xFFFFFFB4 0x00
0x00 0x00 0x48 0x74 0x45 0x58 0x74 0x53
0x6F 0x66 0x74 0x77 0x61 0x72 0x65 0x00
0x40 0x28 0x23 0x29 0x49 0x6D 0x61 0x67
0x65 0x4D 0x61 0x67 0x69 0x63 0x6B 0x20
0x35 0x2E 0x31 0x2E 0x31 0x20 0x30 0x30
0x2F 0x30 0x32 0x2F 0x30 0x31 0x20 0x51
0x3A 0x31 0x36 0x20 0x63 0x72 0x69 0x73
0x74 0x79 0x40 0x6D 0x79 0x73 0x74 0x69
0x63 0x2E 0x65 0x73 0x2E 0x64 0x75 0x70
0x6F 0x6E 0x74 0x2E 0x63 0x6F 0x6D 0x0E
0x4B 0x11 0xFFFFFFB8 0x00 0x00 0x00 0x2A 0x74
0x45 0x58 0x74 0x53 0x69 0x67 0x6E 0x61
0x74 0x75 0x72 0x65 0x00 0x37 0x62 0x63
0x65 0x65 0x36 0x62 0x61 0x63 0x34 0x35
0x33 0x61 0x39 0x37 0x38 0x30 0x65 0x39
0x62 0x30 0x62 0x64 0x62 0x35 0x66 0x64
0x32 0x34 0x66 0x36 0x31 0xFFFFFFA6 0xFFFFFF8B 0x29
0xFFFFFF98 0x00 0x00 0x00 0x00 0x49 0x45 0x4E
0x44 0xFFFFFFAE 0x42 0x60 0xFFFFFF82

Second................

Press any key to continue . . .


Как видно из этой цитаты вариант с cstdio-функциями( все что после надписи "first" ) работает и чтото все-таки прочитано. 
В отличие от первого второй вариант ( все что после слова "Second" ) не вывел ничего!

Как примерно устроено внутри можно почитать Adding Console I/O to a Win32 GUI App

О том как настроить студию на прием данных из STDIN можно почитать Project Settings for a C++ Debug Configuration . А точнее в command argument указать "< filename" (при применении ковычки убрать).

К чему пришел:
На практике мне куда дешевле воспользоваться рабочим вариантом на базе cstdio-библиотеки и работоспособный код копирования из STDIN во временной файл получу куда быстрее, чем еще черт знает сколько времени убивать на разбирательство с STL-стримами.

Однако все же буду очень рад любой подсказке, что не так с вариантом копирования на базе применения С++ стримов ? Где я ошибаюсь? Почему применяя std::cin у меня не пашет?


Это сообщение отредактировал(а) EvilsInterrupt - 9.11.2011, 00:29
PM MAIL WWW ICQ Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0633 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.