Повторение пройденного.

Эта программа ничего не делает. Но в неё можно ввести три целых числа.
Во вложении - архив работающей программы. Зацените.
Совместимость программы: Windows 95, Windows 2000, Windows Vista. Под Windows 95 English version программа показывает кракозябры, потому что не установлен русский шрифт. https://yadi.sk/d/RLzKtXzw3PB4zu [code]// Файл "p11Doc.h"
class CP11Doc:public CDocument
{
protected:
CP11Doc ();
DECLARE_DYNCREATE (CP11Doc);
int aa, ab, ac; // исходные данные - целые числа
int ad, ae; // указатель ввода в строку данных, <Enter>
int ag, ah;
char aj [50]; // место для вводимых символов
int ap [10]; // место хранения данных для вывода на экран
void am (); // перевод данных из символьной формы в цифровую
void an ();
};
// Файл "p11Doc.cpp"
CP11Doc::CP11Doc ()
{
aa = ab = ac = ad = ae = 0;
aj [0] = ap [0] = 0;
}
void CP11Doc::am ()
{
ae = 1;
ag = 0;
while ((aj [ag] < '0' || aj [ag] > '9') && aj [ag] != '-' && aj [ag]) ag++;
an ();
aa = ah;
while ((aj [ag] < '0' || aj [ag] > '9') && aj [ag] != '-' && aj [ag]) ag++;
an ();
ab = ah;
while ((aj [ag] < '0' || aj [ag] > '9') && aj [ag] != '-' && aj [ag]) ag++;
an ();
ac = ah;
}
void CP11Doc::an ()
{
int a;
ah = 0;
a = 1;
if (aj [ag] == '-') {a = -1; ag++;}
while (aj [ag] >= '0' && aj [ag] <= '9')
{
ah = ah * 10 + aj [ag] - '0';
ag++;
}
ah *= a;
}
// Файл "p11View.cpp"
void CP11View::OnDraw (CDC* pDC)
{
CP11Doc* pdoc = GetDocument ();
ASSERT_VALID (pdoc);
CString a;
pDC -> TextOut (10, 10, "Введите три целых числа (Input 3 int):");
pDC -> TextOut (10, 35, pdoc -> aj);
a.Format ("code = %i", pdoc -> ap [0]);
pDC -> TextOut (10, 60, a);
if (pdoc -> ae)
{
a.Format ("%i %i %i", pdoc -> aa, pdoc -> ab, pdoc -> ac);
pDC -> TextOut (10, 85, a);
}
}
void CP11View::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags)
{
CP11Doc *pdoc = GetDocument ();
ASSERT_VALID (pdoc);
pdoc -> ap [0] = nChar;
if (nChar == 8)
{
if (pdoc -> ad) {pdoc -> ad--; pdoc -> aj [pdoc -> ad] = 0;}
goto aaa;
}
if (nChar == 13)
{
pdoc -> am ();
goto aaa;
}
if (pdoc -> ad < 49)
{
pdoc -> aj [pdoc -> ad] = nChar;
pdoc -> aj [pdoc -> ad + 1] = 0;
pdoc -> ad++;
}
aaa:
Invalidate ();
CView::OnChar (nChar, nRepCnt, nFlags);
}[/code]

Комментарии

  • 28 окт 2017 15:30
    Язык программирования - Visual C++ 6.0 для Windows 95 English version ("Help" не установлен).
  • 31 окт 2017 06:26
    Что то мне кажется вы написали слишком много кода для такой простой штуковины. Почему бы не использовать стандартную функцию scanf? Код сократился бы до нескольких строк.
  • 31 окт 2017 06:28
    К сожалению сейчас под рукой нет с++, но покажу аналог на delphi:    
    while Key < 0 do      
     begin        
       ReadLn(S);        
       key := StrToIntDef(s, -1);      
     end;  
    Writeln(S);
    Будет повторять ввод, пока не введете целое число >= 0. Основа тут функция StrToIntDef. Как понятно из имени, эта функция конвертирует строку в целое. Если преобразовать не удалось, тогда она вернет значение по умолчанию. В данном случае -1. Вот и весь секрет.
  • 31 окт 2017 06:29
    Но если вы не ищете легких путей и хотите контролировать ввод каждого символа, тогда можно вот так:

    InputHandle := GetStdHandle(STD_INPUT_HANDLE);

    GetConsoleMode(InputHandle, InputMode);

    SetConsoleMode(InputHandle, 0);


    while c <> #13 do

      begin

        read(c);

        if (c in ['0'..'9']) then

          begin

            write(c);

            s := s + c;

          end;

      end;

      writeln(S);


    SetConsoleMode(InputHandle, InputMode);

  • 31 окт 2017 06:33
    Кстати, гораздо интересней задача на ввод вещественного числа. Попробуйте сделать конечный автомат по вводу вещественного числа. Гарантирую - будет весело :-)
  • 3 ноя 2017 19:09
    Потому что это будет консольный ввод, а я хочу под Windows. Поэтому ввод с клавиатуры обрабатывается событиями Windows.
  • 3 ноя 2017 19:10
    Это я тоже делал.
    У меня задачник. Я хочу решать задачи. Но для этого надо вводить числа. В некоторых задачах можно обойтись целыми числами. Ими я и ограничился.
    Где-то у меня завалялась распечатка про ввод рациональных чисел. Возможно, я ими займусь... как-нибудь позже.
  • 3 ноя 2017 19:11
    Это не окончательный вариант. Я его потом переделал.
  • 4 ноя 2017 04:37
    Ну если события через windows, тогда задача еще упрощается. Про VC не скажу, ибо уже не помню, а вот на Delphi, C++ Builder и C#, это делается элементарно. "Вешаем" обработчик события на поле ввода и пишим такой обработчик:begin
     if not (KeyChar in ['-','+','0'..'9']) then
       KeyChar := #0;
  • 4 ноя 2017 04:39
    Если нужно дополнительно вводить знаки +/-, то немного усложняем:

    procedure TForm1.IntegerInputFilter(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);

    var

     str: string;

    begin

     if (KeyChar in ['-','+','0'..'9']) then

       begin

          if (Sender is TCustomEdit) then

              str := (Sender as TCustomEdit).Text;


          if ((KeyChar in ['+','-']) and (str.Length <> 0)) then

               KeyChar := #0;

       end

     else

       KeyChar := #0;

    end;

  • 4 ноя 2017 04:40
    Если при этом еще и нужно запятую вводить, тогда чуть сложней:

    procedure TForm1.FloatInputFilter(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);

    var

     str: string;

    begin

     if (KeyChar in ['-','+','0'..'9',FormatSettings.DecimalSeparator]) then

       begin

          if (Sender is TCustomEdit) then

              str := (Sender as TCustomEdit).Text;


          if ((KeyChar in ['+','-']) and (str.Length <> 0)) then

               KeyChar := #0

          else

          if (KeyChar = FormatSettings.DecimalSeparator) and (str.Contains(FormatSettings.DecimalSeparator)) then

              KeyChar := #0;

       end

     else

       KeyChar := #0;

    end;