如何在 visual studio 调试控制台中生成 BACKSPACE?
How can I generate an BACKSPACE in a visual studio debug console?
我正在使用 Visual Studio 2019 社区编写 Windows 控制台模式 C 程序。我希望在输入流中看到的每个退格键在输出中打印为 literal 字符串 "\b"
。
如何将退格信号捕获到控制台?如果我按 CTRL-H 它会删除前面的字符,但实际上我要 getchar() 获取相应的值。
while ((c = getchar()) != EOF) {
if (c == '\t') {
printf("\t");
}
else if (c == '\b')
printf("\b");
else if (c == '\') {
printf("\\");
}
else
putchar(c);
Windows 控制台对标准输入执行行编辑处理,允许您使用退格、删除、left/right 光标和 insert/overwrite 模式。这些字符和按键不会导致将字符插入输入流。
您可以使用 Win API SetConsoleMode()
关闭输入处理。例如下面我切换了处理和行输入模式,以便在输入每个字符后 getchar()
returns:
#include <stdio.h>
#include <windows.h>
int main()
{
HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD console_mode = 0 ;
if( GetConsoleMode( stdin_handle, &console_mode) )
{
console_mode = console_mode & ~(ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT) ;
SetConsoleMode( stdin_handle, console_mode ) ;
}
int c = 0 ;
while( (c = getchar()) != EOF )
{
switch( c )
{
case '\t' : printf( "\t" ); break ;
case '\b' : printf( "\b" ); break ;
case '\' : printf( "\\" ); break ;
case '\r' : putchar( '\n' ); break ; // Translate ENTER into Newline
default : putchar( c ); break ;
}
}
}
但是它可能有一些不良的副作用,例如导致 ENTER 被解释为 \r
并且 getchar()
在按下 ENTER 直到下一个字符被输入之后才被解释为 return输入。毫无疑问,有一个解决方案,但我会把它留给你去试验。这可能是标准输入处理和 Windows 控制台处理之间的冲突 - 也许使用 ReadConsole()
和 Win API 控制台 I/O 函数通常会有帮助?
我有一个使用 Win API 和 ReadConsole 的有效解决方案。
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
BOOL readInput(HANDLE hConsoleInput, TCHAR chBuffer, DWORD nNumberOfCharsToRead);
int main(void)
{
DWORD console_mode = 0;
HANDLE stdin_handle;
TCHAR chBuffer = 0;
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
if (GetConsoleMode(stdin_handle, &console_mode))
{
console_mode = console_mode & ~(ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT);
SetConsoleMode(stdin_handle, console_mode);
}
if (stdin_handle == INVALID_HANDLE_VALUE) {
printf("Error getting the handle to the console.\n");
exit(EXIT_FAILURE);
}
while (readInput(stdin_handle, chBuffer, 1)) {
;
}
CloseHandle(stdin_handle);
return 0;
}
BOOL readInput(HANDLE hConsoleInput, TCHAR chBuffer, DWORD nNumberOfCharsToRead)
{
DWORD dwCount;
BOOL bSuccess;
bSuccess = ReadConsole(hConsoleInput, &chBuffer, nNumberOfCharsToRead, &dwCount, NULL);
if (!bSuccess) {
printf("Error reading from the console.\n");
exit(EXIT_FAILURE);
}
switch (chBuffer)
{
case '\t':
printf("\t");
break;
case '\b':
printf("\b");
break;
case '\':
printf("\\");
break;
case '\r':
putchar('\n');
break;
case '\x1a': //EOF
return FALSE;
default:
putchar(chBuffer);
break;
}
return TRUE;
}
我正在使用 Visual Studio 2019 社区编写 Windows 控制台模式 C 程序。我希望在输入流中看到的每个退格键在输出中打印为 literal 字符串 "\b"
。
如何将退格信号捕获到控制台?如果我按 CTRL-H 它会删除前面的字符,但实际上我要 getchar() 获取相应的值。
while ((c = getchar()) != EOF) {
if (c == '\t') {
printf("\t");
}
else if (c == '\b')
printf("\b");
else if (c == '\') {
printf("\\");
}
else
putchar(c);
Windows 控制台对标准输入执行行编辑处理,允许您使用退格、删除、left/right 光标和 insert/overwrite 模式。这些字符和按键不会导致将字符插入输入流。
您可以使用 Win API SetConsoleMode()
关闭输入处理。例如下面我切换了处理和行输入模式,以便在输入每个字符后 getchar()
returns:
#include <stdio.h>
#include <windows.h>
int main()
{
HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD console_mode = 0 ;
if( GetConsoleMode( stdin_handle, &console_mode) )
{
console_mode = console_mode & ~(ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT) ;
SetConsoleMode( stdin_handle, console_mode ) ;
}
int c = 0 ;
while( (c = getchar()) != EOF )
{
switch( c )
{
case '\t' : printf( "\t" ); break ;
case '\b' : printf( "\b" ); break ;
case '\' : printf( "\\" ); break ;
case '\r' : putchar( '\n' ); break ; // Translate ENTER into Newline
default : putchar( c ); break ;
}
}
}
但是它可能有一些不良的副作用,例如导致 ENTER 被解释为 \r
并且 getchar()
在按下 ENTER 直到下一个字符被输入之后才被解释为 return输入。毫无疑问,有一个解决方案,但我会把它留给你去试验。这可能是标准输入处理和 Windows 控制台处理之间的冲突 - 也许使用 ReadConsole()
和 Win API 控制台 I/O 函数通常会有帮助?
我有一个使用 Win API 和 ReadConsole 的有效解决方案。
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
BOOL readInput(HANDLE hConsoleInput, TCHAR chBuffer, DWORD nNumberOfCharsToRead);
int main(void)
{
DWORD console_mode = 0;
HANDLE stdin_handle;
TCHAR chBuffer = 0;
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
if (GetConsoleMode(stdin_handle, &console_mode))
{
console_mode = console_mode & ~(ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT);
SetConsoleMode(stdin_handle, console_mode);
}
if (stdin_handle == INVALID_HANDLE_VALUE) {
printf("Error getting the handle to the console.\n");
exit(EXIT_FAILURE);
}
while (readInput(stdin_handle, chBuffer, 1)) {
;
}
CloseHandle(stdin_handle);
return 0;
}
BOOL readInput(HANDLE hConsoleInput, TCHAR chBuffer, DWORD nNumberOfCharsToRead)
{
DWORD dwCount;
BOOL bSuccess;
bSuccess = ReadConsole(hConsoleInput, &chBuffer, nNumberOfCharsToRead, &dwCount, NULL);
if (!bSuccess) {
printf("Error reading from the console.\n");
exit(EXIT_FAILURE);
}
switch (chBuffer)
{
case '\t':
printf("\t");
break;
case '\b':
printf("\b");
break;
case '\':
printf("\\");
break;
case '\r':
putchar('\n');
break;
case '\x1a': //EOF
return FALSE;
default:
putchar(chBuffer);
break;
}
return TRUE;
}