Как перенаправить стандартный вывод на какой-либо видимый экран в приложении Windows?

Вы можете увидеть ссылку, приведенную ниже, и цитату оттуда. «В C вы должны явно использовать ключевое слово struct для объявления структуры. В C ++ это необязательно после определения типа». См. Ссылку для получения дополнительной информации и примеров.

http://msdn.microsoft.com/en-us/library/64973255%28v=vs.80%29.aspx

37
задан JoeBieg 21 February 2009 в 21:18
поделиться

7 ответов

Это - то, что я сделал бы:

  1. CreatePipe ().
  2. CreateProcess () с дескриптором от CreatePipe () используемый в качестве stdout для нового процесса.
  3. Создают таймер или поток, который называет ReadFile () на том дескрипторе время от времени и помещает чтение данных в текстовое поле или этажерку.
1
ответ дан Andreas Magnusson 21 February 2009 в 21:18
поделиться
  • 1
    I' ve никогда не использовал exception_ptr или current_exception(). I' ve, всегда просто сделанный что-то как throw MyException();. Почему я использовал бы эти два объекта вместо этого? – void.pointer 2 March 2012 в 04:07

Вы могли сделать что-то вроде этого с судом или cerr:

// open a file stream
ofstream out("filename");
// save cout's stream buffer
streambuf *sb = cout.rdbuf();
// point cout's stream buffer to that of the open file
cout.rdbuf(out.rdbuf());
// now you can print to file by writing to cout
cout << "Hello, world!";
// restore cout's buffer back
cout.rdbuf(sb);

Или, можно сделать это с std::stringstream или некоторый другой класс, полученный от std::ostream.

Для перенаправления stdout необходимо было бы вновь открыть дескриптор файла. Этот поток имеет некоторые идеи этой природы.

3
ответ дан greyfade 21 February 2009 в 21:18
поделиться
  • 1
    Превосходная информация, хотя I' m немного перепутанный клонирующимся/самоброшенным материалом Вы говорили о. Вы сказали you cannot hoist a current exception object out of the storage that the implementation’s exception propagation uses который doesn' t действительно имеют любой смысл мне. Можно ли объяснить или связать ли меня с некоторым хорошим материалом чтения по этому? – void.pointer 23 February 2012 в 05:52

Необходимо создать канал (с CreatePipe () ), затем присоединить stdout к, он - конец записи с SetStdHandle () , затем можно читать из конца чтения канала с ReadFile () и поместить текст, который Вы получаете оттуда где угодно, Вам нравится.

18
ответ дан n0rd 21 February 2009 в 21:18
поделиться

Можно перенаправить stdout, stderr и stdin использование freopen.

Из вышеупомянутой ссылки:

/* freopen example: redirecting stdout */
#include <stdio.h>

int main ()
{
  freopen ("myfile.txt","w",stdout);
  printf ("This sentence is redirected to a file.");
  fclose (stdout);
  return 0;
}

можно также запустить программу через командную строку как так:

a.exe > stdout.txt 2> stderr.txt
16
ответ дан Brian R. Bondy 21 February 2009 в 21:18
поделиться
  • 1
    It' s иногда снижающий, как часто люди don' t понимают эту основную причину хранения CSS/JS в их собственных файлах. – Andrew Barber 24 May 2012 в 02:26

При создании процесса с помощью CreateProcess () , можно выбрать HANDLE, к которому stdout и stderr будут записанными. Это HANDLE может быть файлом, к которому Вы направляете вывод.

Это позволит Вам использовать код, не перекомпилировав его. Просто выполните его и вместо того, чтобы использовать system() или этажерка, используйте CreateProcess().

ДЕСКРИПТОР Вы даете CreateProcess(), может также быть ДЕСКРИПТОР канала, который Вы создали, и затем можно читать из канала и сделать что-то еще с данными.

5
ответ дан Peter Mortensen 21 February 2009 в 21:18
поделиться
  • 1
    +1, НО блок проверки допустимости W3C doesn' t как он и материал после " include" не отображался (в Chrome, я did' t тестируют другие браузеры). W3C, которому возражают против сам закрывающий тэг. Я заменил это окончанием </object>, и оно проверило и следующий отображенный материал. – Mawg 27 February 2014 в 13:26

Благодаря ссылка gamedev в ответе greyfade, я смог записать, и протестировать эту простую часть кода

AllocConsole();

*stdout = *_tfdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), _O_WRONLY), _T("a"));
*stderr = *_tfdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE), _O_WRONLY), _T("a"));
*stdin = *_tfdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE), _O_WRONLY), _T("r"));


printf("A printf to stdout\n");
std::cout << "A << to std::cout\n";
std::cerr << "A << to std::cerr\n";
std::string input;
std::cin >> input;

std::cout << "value read from std::cin is " << input << std::endl;

Это работает и достаточно для отладки. Получение текста в более привлекательный элемент GUI взяло бы немного больше работы.

1
ответ дан JoeBieg 21 February 2009 в 21:18
поделиться
  • 1
    Спасибо за Ваш ответ, но меня don' t думают that' s несколько отличающийся, чем загрузка 3 изображений. Мы спрайт для предотвращения этого но Вы все еще имеете опция загрузить 3 изображения и выполнить 3 запроса туда и обратно. – Matt 29 July 2011 в 15:34

Вы, вероятно, ищете что-то вдоль тех строк:

    #define OUT_BUFF_SIZE 512

    int main(int argc, char* argv[])
    {
        printf("1: stdout\n");

        StdOutRedirect stdoutRedirect(512);
        stdoutRedirect.Start();
        printf("2: redirected stdout\n");
        stdoutRedirect.Stop();

        printf("3: stdout\n");

        stdoutRedirect.Start();
        printf("4: redirected stdout\n");
        stdoutRedirect.Stop();

        printf("5: stdout\n");

        char szBuffer[OUT_BUFF_SIZE];
        int nOutRead = stdoutRedirect.GetBuffer(szBuffer,OUT_BUFF_SIZE);
        if(nOutRead)
            printf("Redirected outputs: \n%s\n",szBuffer);

        return 0;
    }

Этот класс сделает это:

#include <windows.h>

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

#ifndef _USE_OLD_IOSTREAMS
using namespace std;
#endif

#define READ_FD 0
#define WRITE_FD 1

#define CHECK(a) if ((a)!= 0) return -1;

class StdOutRedirect
{
    public:
        StdOutRedirect(int bufferSize);
        ~StdOutRedirect();

        int Start();
        int Stop();
        int GetBuffer(char *buffer, int size);

    private:
        int fdStdOutPipe[2];
        int fdStdOut;
};

StdOutRedirect::~StdOutRedirect()
{
    _close(fdStdOut);
    _close(fdStdOutPipe[WRITE_FD]);
    _close(fdStdOutPipe[READ_FD]);
}
StdOutRedirect::StdOutRedirect(int bufferSize)
{
    if (_pipe(fdStdOutPipe, bufferSize, O_TEXT)!=0)
    {
        //treat error eventually
    }
    fdStdOut = _dup(_fileno(stdout));
}

int StdOutRedirect::Start()
{
    fflush( stdout );
    CHECK(_dup2(fdStdOutPipe[WRITE_FD], _fileno(stdout)));
    ios::sync_with_stdio();
    setvbuf( stdout, NULL, _IONBF, 0 ); // absolutely needed
    return 0;
}

int StdOutRedirect::Stop()
{
    CHECK(_dup2(fdStdOut, _fileno(stdout)));
    ios::sync_with_stdio();
    return 0;
}

int StdOutRedirect::GetBuffer(char *buffer, int size)
{
    int nOutRead = _read(fdStdOutPipe[READ_FD], buffer, size);
    buffer[nOutRead] = '\0';
    return nOutRead;
}

Вот результат:

1: stdout
3: stdout
5: stdout
Redirected outputs:
2: redirected stdout
4: redirected stdout
14
ответ дан 4 revs, 2 users 74%Cedric Perthuis 21 February 2009 в 21:18
поделиться
  • 1
    Получающееся DOM-дерево не то, как будто включенный файл был дословно заменен. Целый документ включая < html> и < body> теги вставляются во включение документа. – scravy 21 October 2012 в 07:41
Другие вопросы по тегам:

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