scanf
но не понятно, как сделать редактирование по Backspace.
По Backspace печатаешь в консоли "\b \b" (Здесь '\b' - это и есть бэкспэйс, только насколько я помню из опыта программирования под ДОС, он возвращает каретку на один символ назад, но при этом не затирает символ, поэтому приходится печатать пробел и снова бэкспэйс. Может быль я ошибаюсь.)
Напиши свою функцию, это просто. Только не забудь проверять положение каретки а строке (типа если крайнее левое, то бэкспэйс игнорируется).
У консоли есть одно забавное свойство. Если курсор находится в нижней (25-ой) строке, и вводишь строку длиной более 80 символов, курсор (как и положено) передвигается на строку ниже. Так вот. В ДОСе после этого нельзя было вернуться обратно на верхнюю строку. А в cmd.exe - можно.
И еще. scanf (как и printf) - очень сложная функция. Мне кажется, она построена на вызовах того же getch().
int OnBSpaceCursor(int i)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hIn=GetStdHandle(STD_INPUT_HANDLE);
if(i>0)
{
GetConsoleScreenBufferInfo(hOut,&csbi);
COORD cr;
if(csbi.dwCursorPosition.X==0)
{
cr.X=csbi.dwSize.X-1;
cr.Y=csbi.dwCursorPosition.Y-1;
}
else {
cr.X=csbi.dwCursorPosition.X-1;
cr.Y=csbi.dwCursorPosition.Y;
}
SetConsoleCursorPosition(hOut,cr);
int fp=SetFilePointer(hOut,NULL,NULL,FILE_CURRENT);
SetFilePointer(hOut,-1,NULL,FILE_CURRENT);
DWORD nWr;
WriteFile(hOut," ",1,&nWr,NULL);
SetConsoleCursorPosition(hOut,cr);
}
return 0;
}
int OnArrowLeftCursor()
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hIn=GetStdHandle(STD_INPUT_HANDLE);
if(i>0)
{
GetConsoleScreenBufferInfo(hOut,&csbi);
COORD cr;
if(csbi.dwCursorPosition.X==0)
{
cr.X=csbi.dwSize.X-1;
cr.Y=csbi.dwCursorPosition.Y-1;
}
else {
cr.X=csbi.dwCursorPosition.X-1;
cr.Y=csbi.dwCursorPosition.Y;
}
SetConsoleCursorPosition(hOut,cr);
int fp=SetFilePointer(hOut,NULL,NULL,FILE_CURRENT);
SetFilePointer(hOut,-1,NULL,FILE_CURRENT);
}
return 0;
}
int OnArrowRightCursor()
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hIn=GetStdHandle(STD_INPUT_HANDLE);
if(i>0)
{
GetConsoleScreenBufferInfo(hOut,&csbi);
COORD cr;
if(csbi.dwCursorPosition.X==csbi.swSize.X-1)
{
cr.X=0;
cr.Y=csbi.dwCursorPosition.Y+1;
}
else {
cr.X=csbi.dwCursorPosition.X+1;
cr.Y=csbi.dwCursorPosition.Y;
}
SetConsoleCursorPosition(hOut,cr);
int fp=SetFilePointer(hOut,NULL,NULL,FILE_CURRENT);
SetFilePointer(hOut,1,NULL,FILE_CURRENT);
}
return 0;
}
int GetInput(char *szstr)
{
int i=0;
char ch;
while(ch!=KEY_RETURN)
{
ch=_getch();
switch(ch)
{
case KEY_RETURN:
szstr='\0';
printf("\n");
break;
case KEY_BACKSPACE:
OnBSpaceCursor(i);
i--;
break;
case KEY_ARROW_LEFT:
OnArrowLeftCursor();
break;
case KEY_ARROW_RIGHT:
OnArrowRightCursor();
break;
default:
szstr=ch;
printf("%c",ch);
i++;
break;
}
}
return 0;
}
вроде работает...
также забыл сдвигать правую часть строки, если курсор находится не в конце строки.
А что должен делать этот монстр?
У меня навязчивое впечатление, что ты "изобретаешь велосипед".
Зачем тебе аналог scanf и чем не подошел сам scanf?
Очень просто: мне нужно обрабатывать каждый символ по-своему: обычные символы просто выводить, а по TAB автоматически дополнять введенное слово подходящей частью из заранее определенного списка. Из-за этого все проблемы. Еще хотелось бы комбинации обрабатывать типа Ctrl+K, но я чувствую, что это невозможно.
Очень просто: мне нужно обрабатывать каждый символ по-своему: обычные символы просто выводить, а по TAB автоматически дополнять введенное слово подходящей частью из заранее определенного списка. Из-за этого все проблемы. Еще хотелось бы комбинации обрабатывать типа Ctrl+K, но я чувствую, что это невозможно.
А как ты предполагал использовать scanf ?
А как ты предполагал использовать scanf ?
Никак. Он мне не подходит, потому что разбирать каждый символ можно только после окончания ввода. То, что я хочу сделать похоже на редактирование командной строки в юниксовых шеллах типа bash.
Мне тут рекомендуют из консоли создать еще одно окно с SW_HIDE и там ловить WM_KEYDOWN.
Никак. Он мне не подходит, потому что разбирать каждый символ можно только после окончания ввода. То, что я хочу сделать похоже на редактирование командной строки в юниксовых шеллах типа bash.
Мне тут рекомендуют из консоли создать еще одно окно с SW_HIDE и там ловить WM_KEYDOWN.
А не проще ли использовать _getch() ?
Так и комбинации с Ctrl, Alt и т.п. отследить можно.
Так и комбинации с Ctrl, Alt и т.п. отследить можно.
Это очень интересно, про Ctrl и Alt по-подробнее, пожалуйста
Это очень интересно, про Ctrl и Alt по-подробнее, пожалуйста
The _getch and _getwch functions read a single character from the console without echoing. _getche and _getwche read a single character from the console and echo the character read. None of these functions can be used to read CTRL+C. When reading a function key or an arrow key, each function must be called twice; the first call returns 0 or 0xE0, and the second call returns the actual key code.
The _getch and _getwch functions read a single character from the console without echoing. _getche and _getwche read a single character from the console and echo the character read. None of these functions can be used to read CTRL+C. When reading a function key or an arrow key, each function must be called twice; the first call returns 0 or 0xE0, and the second call returns the actual key code.
Вот черт, о двойном вызове я и не знал...:roll:
Вот черт, о двойном вызове я и не знал...:roll:
Двойной вызов это для различных функциональных клавишь (F1..F12, Insert, Home и т.д.).
Но вот Ctrl, Shft всеравно отслеживается:
{
int ch = _getch();
printf("0x%X\n",ch);
}
<D> ch = 0x44
<Alt+D> ch = 0x64
<Ctrl+D> ch = 0x4
<Shft+D> ch = 0x64