Pregunta

Me pregunto si hay alguna forma (en C) de obtener el contenido del búfer de la consola, preferiblemente como algún tipo de matriz de caracteres. Se escribirá en un archivo, así que si me estoy perdiendo algo estúpido que hará exactamente eso, entonces apúntelo. Puede ser específico de Windows. Estoy usando MinGW (gcc 3.4.5).

Gracias de antemano.

¿Fue útil?

Solución

Creo que necesita echar un vistazo a las funciones de la consola win32, por ejemplo GetStdHandle () , ReadConsoleOutput () , WriteConsoleOutput etc. .

Otros consejos

En Win32, ReadConsoleOutput :

  

Lee datos de atributos de color y caracteres de un bloque rectangular de celdas de caracteres en un búfer de pantalla de consola, y la función escribe los datos en un bloque rectangular en una ubicación específica en el búfer de destino.

Descargar mingw-readline

Y mira GNU Readline

rl_line_buffer

Si es la pantalla en una ventana de comando, entonces potencialmente no, o no es una manera fácil. Puede piratear los eventos de Windows para seleccionar todo, copiar y leer el portapapeles.

Aquí hay una manera de leer el búfer de la consola. GetNumCharsInConsoleBuffer es para obtener el total de caracteres escritos en el búfer de la pantalla de la consola, utilizo GetConsoleScreenBufferInfo dentro. Después, creo una matriz de tamaño asignada dinámicamente igual al valor anterior devuelto por GetNumCharsInConsoleBuffer + 1 (para el final cero). Y finalmente, ReadConsoleBuffer llenará el búfer recién creado con el contenido del búfer de la pantalla de la consola. Después, si desea escribir el contenido de su búfer en un archivo, probablemente tendrá que formatearlo. Con ReadConsoleOutputCharacter usted obtener una región (rectángulo) del búfer de la pantalla de la consola. Las líneas que escribió en el búfer de la pantalla de la consola se rellenarán con espacios para ajustarse a la región del búfer. será lo mismo con el win32 ReadConsoleOutput / WriteConsoleOutput , obtendrá una región (rectángulo) de su pantalla.

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

DWORD GetNumCharsInConsoleBuffer()
{
    CONSOLE_SCREEN_BUFFER_INFO buffer_info = {0};
    if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &buffer_info) != FALSE)
        return (DWORD) ( (buffer_info.dwSize.X * ( buffer_info.dwCursorPosition.Y + 1)) - (buffer_info.dwSize.X - ( buffer_info.dwCursorPosition.X)) );
    else
        return 0;
}

DWORD ReadConsoleBuffer(char* buffer, DWORD bufsize)
{
    DWORD num_character_read = 0;
    COORD first_char_to_read = {0};
    if( ReadConsoleOutputCharacterA(GetStdHandle(STD_OUTPUT_HANDLE), buffer, bufsize, first_char_to_read, &num_character_read) != FALSE)
        buffer[bufsize-1] = '\0';
    else
        buffer[0] = '\0';

    return num_character_read;
}

int main(int argc, char** argv)
{
    fprintf(stdout, "Writting\nin\nthe\nbuffer\n");
    DWORD bufsize = GetNumCharsInConsoleBuffer();

    if(bufsize > 0)
    {
        bufsize++; // Add 1 for zero-ending char

        char* buffer = malloc(bufsize);
        memset(buffer, 0, bufsize);

        ReadConsoleBuffer(buffer, bufsize);  

        puts("\nBuffer contents:");
        puts(buffer);

        free(buffer);
    }

    system("pause"); 
    return 0;
}

Salida:

Writting
in
the
buffer
Buffer contents:
Writting
in
the
buffer

Appuyez sur une touche pour continuer...

EDITAR:

Acabo de escribir una función que puede usarse para escribir el contenido del búfer de pantalla en el archivo. Esta función elimina los espacios acolchados del búfer de la consola de la pantalla. ReadConsoleBuffer toma un puntero de caracteres nulo como primer argumento ( buffer ) que se asignará durante su ejecución. Así que no olvides eliminarlo tú mismo. ReadConsoleBuffer escribirá el tamaño del búfer en el segundo argumento ( bufsize ).

#include <stdio.h>
#include <stdlib.h>
#include <crtdbg.h>
#include <Windows.h>

const char* ReadConsoleBuffer(char** buffer, size_t* bufsize)
{
    CONSOLE_SCREEN_BUFFER_INFO buffer_info = {0};
    if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &buffer_info) != FALSE )
    {
        size_t data_size = (size_t) ( (buffer_info.dwSize.X * ( buffer_info.dwCursorPosition.Y + 1)) - 
                                      (buffer_info.dwSize.X - ( buffer_info.dwCursorPosition.X + 1)) );

        if(data_size > 1)
        {
            char* data = malloc(data_size); //= new char[data_size];
            _ASSERTE(data != 0);

            DWORD num_char_read;
            COORD first_char_read = {0};
            if( ReadConsoleOutputCharacterA(GetStdHandle(STD_OUTPUT_HANDLE), data, data_size, first_char_read, &num_char_read) != FALSE )
            {
                data[data_size-1] = '\0';

                const char* const pbeg = &data[0];
                const char* const pend = &data[data_size-1];
                char* pcur, *pmem;

                const int line_size = buffer_info.dwSize.X;
                int line_count = buffer_info.dwCursorPosition.Y;

                if(buffer_info.dwCursorPosition.X > 0) // No new line char at the end of the last line, so no padded spaces. 
                {                    
                    if((line_count + 1) > 1)
                    {
                        pmem = &data[data_size - buffer_info.dwCursorPosition.X - 1];
                        pcur = (pmem - 1);
                    }
                    else // 1 line and no new line char(no padded spaces). Will no enters the loop.
                        pcur = &data[0];
                }
                else 
                {
                    pcur = &data[data_size-2];
                    pmem = 0;
                }

                if(pcur != pbeg)
                {
                    while(1)
                    {
                        line_count--;

                        while(*pcur == ' ') { pcur--; }
                        *(pcur + 1) = '\n'; // Padded spaces replaced by new line char.

                        if(!pmem) // first round. Add zero-ending char.
                            *(pcur + 2) = '\0'; 
                        else
                            memmove(pcur + 2, pmem, (pend - pmem) + 1);

                        if(line_count == 0)
                            break;

                        pmem = &data[line_count * line_size];
                        pcur = (pmem - 1);
                    }
                }

                *bufsize = strlen(data) + 1;

                *buffer = malloc(*bufsize); //= new char[*bufsize];
                _ASSERTE(*buffer != 0);

                memcpy(*buffer, data, *bufsize);
                free(data); //delete[] data;

                pcur= *buffer;
                return pcur;
            }

            if(data)
                free(data); // delete[] data;
        }
    }

    *buffer = 0;
    return 0;
}


int main(int argc, char** argv)
{
    printf("Writting\nin\nthe\nbuffer");

    char* buffer;
    size_t size;  
    ReadConsoleBuffer(&buffer, &size);

    if(buffer)
    {
        freopen("out.txt", "w", stdout); 
        fprintf(stdout, buffer);
        free(buffer);
        fclose(stdout);
    }  

    return 0;
}

Salida en 'out.txt':

Writting
in
the
buffer
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top