Просто интересно, есть ли способ (в C) получить содержимое буфера консоли, желательно в виде какого-то массива символов. Он будет записан в файл, поэтому, если я упускаю какую-то глупость, которая будет делать именно это, укажите на это. Это может быть специфично для Windows. Я использую MinGW (gcc 3.4.5).
Заранее спасибо.





Если это экран в командном окне, то потенциально нет или непростой путь. Вы можете взломать события Windows, чтобы выделить все, скопировать и прочитать буфер обмена.
Я думаю, вам нужно взглянуть на функции консоли win32, например GetStdHandle (), ReadConsoleOutput (), WriteConsoleOutput и т. д.
альтернативы linux?
В Win32 ReadConsoleOutput:
Reads character and color attribute data from a rectangular block of character cells in a console screen buffer, and the function writes the data to a rectangular block at a specified location in the destination buffer.
Вот способ прочитать буфер консоли. GetNumCharsInConsoleBuffer предназначен для получения общего количества символов, записанных в экранном буфере консоли, я использую GetConsoleScreenBufferInfo внутри. После этого я создаю динамически распределяемый массив размером, равным предыдущему значению, возвращенному GetNumCharsInConsoleBuffer + 1 (для нулевого конца). И, наконец, ReadConsoleBuffer заполнит только что созданный буфер содержимым экранного буфера консоли.
После этого, если вы захотите записать содержимое вашего буфера в файл, вам, вероятно, потребуется выполнить некоторое форматирование. С помощью ReadConsoleOutputCharacter вы получаете область (прямоугольник) экранного буфера консоли. Строки, которые вы записали в экранный буфер консоли, будут заполнены пробелами, чтобы соответствовать области буфера. то же самое будет и с win32 ReadConsoleOutput/WriteConsoleOutput, вы получите область (прямоугольник) вашего экрана.
#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;
}
Выход:
Writting
in
the
buffer
Buffer contents:
Writting
in
the
buffer
Appuyez sur une touche pour continuer...
Обновлено:
Я просто написал функцию, которую можно использовать для записи содержимого экранного буфера в файл. Эта функция удаляет заполненные пробелы из буфера экранной консоли.
ReadConsoleBuffer принимает нулевой указатель на символ в качестве первого аргумента (buffer), который будет выделен во время его выполнения. Так что не забудьте удалить его самостоятельно. ReadConsoleBuffer запишет размер буфера во второй аргумент (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;
}
Вывод в out.txt:
Writting
in
the
buffer
Вы должны иметь в виду консоль, верно? Я уточню это в вопросе. Массивы символов Windows (если вы не имеете в виду искусство ascii) было бы довольно сложно;)