BOOL ReadConsole(
HANDLE hConsoleInput, // handle of a console input buffer
LPVOID lpBuffer, // address of buffer to receive data
DWORD nNumberOfCharsToRead, // number of characters to read
LPDWORD lpNumberOfCharsRead, // address of number of characters read
LPVOID lpReserved // reserved
);
Ввод любого числа символов через ReadConsole
http://forum.codenet.ru/showthread.php?t=41635;до сих пор не знаю,как исправить) прочесть любое количество символов?Ведь эти функции используют заранее установленный размер буфера,т.е. больше,чем он задан,ввести не получится
Вот,например,когда вводишь в текстовое поле,там можно много ввести,и не надо ограничиваться чем-то,фактически,и потом можно получить длину введённого текста.Как можно поступить в случае с консолью?
Как можно с помощью ReadConsole(или WriteFile,ибо с ReadConsole глюки,читайте
Вот,например,когда вводишь в текстовое поле,там можно много ввести,и не надо ограничиваться чем-то,фактически,и потом можно получить длину введённого текста.Как можно поступить в случае с консолью?
Повторять чтение пока читается.
А что повторять-то?После вызова функции в буфере окажется столько символов,сколько было введено+CRLF(если введено < размера буфера) или не более,чем резмер буфера.В том-то и вопрос,как быть–получить все введённые данные при том условии,что заранее неизвестно,сколько их будет?
Либо использовать функции "низкоуровневого" ввода-вывода, но это не даст возможности перенаправлять ввод-вывод и прибавит много сложностей.
Тогда,кстати,не получится сделать позиционирование в строке(т.е. при обнаружении ошибки придётся удалять все символы до неё;прям как в DOS:))
С низкоуровневым тоже неохота заморачиваться…да и нет особой нужды в нём
Тогда,кстати,не получится сделать позиционирование в строке
Да, это верно. Вернее я не знаю, как сделать по-другому, потому что пока не приходилось. Можно ограничить строку заведомо большой длиной, в подавляющем большинстве случаев такой вариант подходит. Например 80 - ширина чаще всех используемого текстового видеорежима, или 255 - максимальная длина файла (если не изменяет память).
Цитата: Vov4ick
Можно ограничить строку заведомо большой длиной, в подавляющем большинстве случаев такой вариант подходит. Например 80 - ширина чаще всех используемого текстового видеорежима, или 255 - максимальная длина файла (если не изменяет память).
В том-то и дело,что неохота ограничиваться заведомо большей длиной…хотя это фактически единственное решение.Просто кто-то может взять и перевалить за этот лимит:rolleyes:
А память тебе всё-таки с кем-то изменяет;).Для ANSI-версии максимальная длина имени файла–260 символов(Max_Path)
Код:
в lpNumberOfCharsRead сохраняется реально считанное количество байт. повторяешь чтение пока количество считанных байт не станет равным нулю.
Я так понял?
да, именно так.
Большое спасибо,товарищи,что наставили на путь истинный.Благодаря вам я нашёл ответ на вопрос,заданный в теме http://forum.codenet.ru/showthread.php?t=41635
Имеющим такой же вопрос сообщаю:ежели размер заданного Вами буфера меньше введённого Вами числа символов,то следующий вызов ReadConsole/ReadFile вернётся сразу же(без задержки и запроса на ввод),причём оставшиеся символы будут переданы в буфер заново,но без повторного отображения оных на экране.Если что-то до сих пор непонятно–просьба обращаться в личку,а не заставлять уважаемых форумчан заново объяснять это
Ещё раз благодарю за помощь:)
Допустим,я хочу считать только 1 символ.Соответственно,nNumberOfCharsToRead я присваиваю 1.Но,согласно написанному выше,в буфере останутся символы,которые мне не нужны,и при следующем вызове ReadConsole они прочтутся,что мне не надо.Так вот,как очистить входной буфер?
Нашёл функцию FlushConsoleInputBuffer,это то,что мне надо?
Upd:попробовал эту функцию.Она вернула 1,но буфер не очистила.Т.е. следующий вызов ReadConsole проскочил без задержки(прочёл 0x0D,0x0A вместо того,чтобы ждать пользовательского ввода).Не подходит )=
FlushConsoleInputBuffer ни разу не упоминается в описании ReadConsole, зато она упоминается в описании ReadConsoleInput. Следовательно, flush нужно применять именно с ReadConsoleInput.
Тестовый пример показал, что FlushConsoleInputBuffer действительно не оказывает никакого действия на последующее применение ReadConsole.
Более внимательное ознакомление с доками выявило следующее: FlushConsoleInputBuffer относится к низкоуровневым консольным функциям - Low-Level Console Input Functions, в то время как ReadConsole является высокоуровневой - High-Level. Стало быть, не судьба применить её в этом контексте.
Придётся очищать консоль ввода применением ReadConsole в цикле, пока кол-во считанных символов не станет 0 (или меньше размера буфера) или буфер для ввода делать 64К и одним махом в него читать всё оставшееся.
ЗЫ: если найдёшь более кошерный способ - отпишись, мне тоже любопытно.
Да,я так и делал,в общем-то…просто тут появилась одна запара с этим очищением,а я надеялся схалтурить.Не тут-то было
В [COLOR="Silver"]светлом обозримом[/COLOR] будущем,возможно,перейду на низкоуровневые функции–по крайней мере,там можно очистить буфер:)