只是想知道是否有任何方法(在 C 中)来获取控制台缓冲区的内容,最好是某种 char 数组。它将被写入一个文件,所以如果我错过了一些愚蠢的东西,可以做到这一点,然后指出它。它可以是特定于 Windows 的。我正在使用 MinGW (gcc 3.4.5)。
提前致谢。
我认为您需要查看 Win32 控制台功能,例如GetStdHandle()、 ReadConsoleOutput()、WriteConsoleOutput等。
在 Win32 中,ReadConsoleOutput:
从控制台屏幕缓冲区中的字符单元的矩形块读取字符和颜色属性数据,该函数将数据写入目标缓冲区中指定位置的矩形块。
这是一种读取控制台缓冲区的方法。GetNumCharsInConsoleBuffer
是获取控制台屏幕缓冲区中写入的总字符数,我在里面使用了GetConsoleScreenBufferInfo。之后,我创建一个动态分配的数组,其大小等于 + 1 返回的先前值GetNumCharsInConsoleBuffer
(对于零结尾)。最后,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 事件以全选、复制和读取剪贴板。