Obtenir le contenu du tampon de la console en C
Question
Je me demandais simplement s’il existait un moyen (en C) d’obtenir le contenu du tampon de la console, de préférence sous forme de tableau de caractères. Il va être écrit dans un fichier, donc si je manque quelque chose de stupide qui fera exactement cela, alors faites-le remarquer. Cela peut être spécifique à Windows. J'utilise MinGW (gcc 3.4.5).
Merci d'avance.
La solution
Je pense que vous devez examiner les fonctions de la console Win32, par exemple GetStdHandle () , ReadConsoleOutput () , WriteConsoleOutput , etc. .
Autres conseils
Dans Win32, ReadConsoleOutput :
Lit les données d'attributs de caractères et de couleurs d'un bloc rectangulaire de cellules de caractères dans un tampon d'écran de la console, puis la fonction écrit les données dans un bloc rectangulaire situé à un emplacement spécifié dans le tampon de destination.
S'il s'agit de l'écran dans une fenêtre de commande, il est alors potentiellement impossible ou impossible. Vous pouvez pirater les événements Windows pour tout sélectionner, copier et lire le presse-papiers.
Voici un moyen de lire le tampon de la console. GetNumCharsInConsoleBuffer
consiste à obtenir le nombre total de caractères écrits dans le tampon d'écran de la console. J'utilise GetConsoleScreenBufferInfo à l'intérieur. Ensuite, je crée un tableau alloué dynamiquement de taille égale à la valeur précédemment renvoyée par GetNumCharsInConsoleBuffer
+ 1 (pour la terminaison zéro). Et enfin, ReadConsoleBuffer
remplira le tampon qui vient d'être créé avec le contenu du tampon d'écran de la console.
Ensuite, si vous souhaitez écrire le contenu de votre tampon dans un fichier, vous devrez probablement procéder à un certain formatage. Avec LireConsoleOutputCharacter obtenir une région (rectangle) du tampon d'écran de la console. Les lignes que vous avez écrites dans le tampon d'écran de la console seront complétées d'espaces pour s'adapter à la région du tampon. ce sera la même chose avec le win32 ReadConsoleOutput / WriteConsoleOutput
, vous obtiendrez une région (rectangle) de votre écran.
#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;
}
Sortie:
Writting
in
the
buffer
Buffer contents:
Writting
in
the
buffer
Appuyez sur une touche pour continuer...
EDIT:
Je viens d'écrire une fonction qui peut être utilisée pour écrire le contenu du tampon d'écran dans un fichier. Cette fonction supprime les espaces remplis de la mémoire tampon de la console d’écran.
ReadConsoleBuffer
prend comme premier argument un pointeur de caractère vide ( buffer
) qui sera alloué lors de son exécution. Alors n'oubliez pas de le supprimer vous-même. ReadConsoleBuffer
écrira la taille du tampon dans le deuxième argument ( 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;
}
Sortie dans 'out.txt':
Writting
in
the
buffer