Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.58/12: Рейтинг темы: голосов - 12, средняя оценка - 4.58
Kir964
0 / 0 / 0
Регистрация: 21.10.2014
Сообщений: 4
1

Edit и отрицательные числа

26.10.2014, 23:55. Просмотров 2507. Ответов 18
Метки нет (Все метки)

Здравствуйте !
Помогите решить проблему .
Пользуюсь С builder XE6 . В поле Edit не могу ввести отрицательное число , точнее вообще знак минус . Выдаёт ошибку "Is not a valid floating point value "

Вот часть кода .
C++
1
2
3
4
5
float x1, x2, x3, y1, y2, y3;
void __fastcall TForm1::Edit1Change(TObject *Sender) {
 
    x1 = StrToFloat(Edit1->Text);
}
Пробовал прописывать определенные символы и числа , а именно от 0-9 символ "-" "," в сообытии PressKey , выдаёт такую же ошибку .

Помогите неучу пожалуйста .
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.10.2014, 23:55
Ответы с готовыми решениями:

Проверка числа в Edit
Доброе время суток. Проблема такая. Есть поле Edit. Необходимо, чтобы при событии OnExit...

Случайные числа выводящиеся в Edit
Привет всем, возникла проблема, нужно что бы при нажатии на кнопку(Button1) выводилось случайное...

Преобразование числа в строку из edit
Здравствуйте. Ситуация оч глупая. В аксесе я сделал связи Счётчик-код (1-многим), и мне нужно...

Округлить числа в поле Edit
Добрый день! Не могу разобраться как округлить числа в поле Edit в которых вывожу результат. ...

От числа в Edit меняется количество формул
Здравствуйте подскажите пожалуйста есть такой код void __fastcall TForm1::Button1Click(TObject...

18
Max Dark
шКодер самоучка
1998 / 1765 / 870
Регистрация: 09.10.2013
Сообщений: 3,896
Записей в блоге: 6
Завершенные тесты: 2
27.10.2014, 00:23 2
У меня нет Builder-a, но, наверное, оборачивание в try/catch должно помочь
C++
1
2
3
4
5
6
try {
    x1 = StrToFloat(Edit1->Text);
}
catch(...) {
// здесь ваши действия на некоректный ввод
}
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
27304 / 18271 / 7231
Регистрация: 22.10.2011
Сообщений: 32,175
Записей в блоге: 6
27.10.2014, 00:37 3
Зачем исключения ловить?
C++
1
    x1 = StrToFloatDef(Edit1->Text, 0);
Пока будет некорректное значение - x1 будет нулевым. Ну, или какое-то другое дефолтное значение выбрать...
2
gunslinger
случайный прохожий
1396 / 897 / 349
Регистрация: 20.07.2013
Сообщений: 2,555
27.10.2014, 01:22 4
А лучше выставь у Edit свойство NumbersOnly в 0 (false) для начала и потом пропиши ограничения по вводу.
Причем название свойства следовало "обозвать" DigitsOnly (только цифры в противоположность числам, для меня эта разница более чем очевидная - цифра является числом, но обратное "число есть цифра" в общем случае не верно), ибо ни разделить десятичной точки, ни знак отрицательного числа вручную нельзя ввести. Даже не знаю, чем думали разработчики IDE. Может у них там своя логика.
0
27.10.2014, 01:22
D1973
Модератор
4216 / 3033 / 1457
Регистрация: 21.01.2014
Сообщений: 12,971
Записей в блоге: 3
Завершенные тесты: 1
27.10.2014, 10:50 5
Цитата Сообщение от Kir964 Посмотреть сообщение
void __fastcall TForm1::Edit1Change(TObject *Sender)
Ну так ты в каком событии делаешь преобразование?
Ты набираешь знак -, происходит событие OnChange и, соответсвенно, попытка преобразовать этот текст "-" в число с плавающей точкой. Если ты сначала введешь число, потом вернешься на первую позицию строки ввода и поставишь знак -, то никакой ошибки не возникнет.
Так что подумай, где производить это преобразование StrToFloat
0
krv
74 / 54 / 17
Регистрация: 10.07.2014
Сообщений: 329
27.10.2014, 12:32 6
Стандартно обработку завершения ввода числа вводят в OnKeyPress
а в OnChange только проверяют на недопустимость символов, если надо. Имхо, проще всего сделать так:
C++
1
2
3
4
5
6
7
8
9
10
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
  if (Key==13) {// code of "Enter"
    try {
      x1 = StrToFloat(Edit1->Text);
    } catch(...) {
    //неправильно введенное число, обругать пользователя
      Edit1->Text =""; 
    }
}
1
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
27304 / 18271 / 7231
Регистрация: 22.10.2011
Сообщений: 32,175
Записей в блоге: 6
27.10.2014, 13:36 7
То есть, лишь бы набыдлокодить? Понятно. Извините, что влез с решением, которое обходится без отлова исключений... Больше не повторится...
0
krv
74 / 54 / 17
Регистрация: 10.07.2014
Сообщений: 329
27.10.2014, 13:43 8
Хм. Я почему то решил что в данной теме решили предложить несколько различных вариантов решения.
А уж ТС выберет лучшее для его ситуации.
Например твое решение хорошее, но в нем нельзя реализовать предупреждение человеку, о том что он ввел неправильные данные.
А использовать дефолтное значение при ручном вводе - тоже как бы не фонтан...
0
SatanaXIII
Почетный модератор
Эксперт С++
5796 / 2791 / 385
Регистрация: 01.11.2011
Сообщений: 6,798
Завершенные тесты: 1
27.10.2014, 14:27 9
krv, UI вам намекает на TryStrToFloat().
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
27304 / 18271 / 7231
Регистрация: 22.10.2011
Сообщений: 32,175
Записей в блоге: 6
27.10.2014, 15:21 10
Неправда, я написал выше, в третьем посте, что имелось в виду... На фиг мне был бы там нужен еще Try..., если после него надо опять проверять результат? Я одной командой бы сделал то, что нужно, безо всяких проверок.
0
Avazart
Эксперт С++
7909 / 5732 / 566
Регистрация: 10.12.2010
Сообщений: 26,229
Записей в блоге: 17
27.10.2014, 15:36 11
Да зависит от "политики партии".

Но обычно приходится проверять дважды один раз при вводе, второй раз при присвоении значения и начале расчетов.

А давать возможность пользователю считать по дефолтными значениям при неправильном вводе без единого предупреждения тоже не всегда допустимо.
0
krv
74 / 54 / 17
Регистрация: 10.07.2014
Сообщений: 329
27.10.2014, 15:41 12
C++
1
2
3
4
5
6
7
8
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
  if (Key==13) {// code of "Enter"
    if (!TryStrToFloat(Edit1->Text,x1)) {
    //неправильно введенное число, обругать пользователя
      Edit1->Text =""; 
    }
}
Да можно и так... Но я подозреваю, что внутри этого TryStrToFloat опять же
C++
1
2
3
4
try {
  out = StrToFloat(Edit1->Text);
} catch(...) {
}
Так что в лоб, что по лбу..
0
Avazart
Эксперт С++
7909 / 5732 / 566
Регистрация: 10.12.2010
Сообщений: 26,229
Записей в блоге: 17
27.10.2014, 16:05 13
Как пример сообщение в лейбл о некорректом вводе.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <System.RegularExpressions.hpp>
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Edit1->Text= "0";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    float x1;
    try
    {
        x1 = StrToFloat(Edit1->Text);
        //...
    }
    catch(const Exception& E)
    {
        ShowMessage("Некорректно заданны исх.данные "+E.Message);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
    TRegEx Re("^((-?\\d+)|(-?\\d+,\\d*))$");
    if(Re.IsMatch(Edit1->Text) )
    {
        Label1->Font->Color= clLime;
        Label1->Caption= "Ok!";
    }
    else
    {
        Label1->Font->Color= clRed;
        Label1->Caption= "Ошибочный ввод!";
    }
}
//---------------------------------------------------------------------------

Видео
1
Avazart
Эксперт С++
7909 / 5732 / 566
Регистрация: 10.12.2010
Сообщений: 26,229
Записей в блоге: 17
27.10.2014, 18:28 14
Подумал можно еще сделать c откатом значения и подсказкой:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <System.RegularExpressions.hpp>
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Edit1->Text= "0";
    BalloonHint1->Title= "Ошибка:";
    BalloonHint1->Description= "Некорректный ввод!";
    BalloonHint1->Delay= 10;
    BalloonHint1->HideAfter= 500;
    BalloonHint1->ImageIndex= 1;
}
//---------------------------------------------------------------------------
String OldEditValue="";
int  CaretPos= 0;
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
    TRegEx Re("^((-?\\d+)|(-?\\d+,\\d*))$");
    if(Re.IsMatch(Edit1->Text) )
    {
        OldEditValue= Edit1->Text; 
    }
    else
    {
        Edit1->Text= OldEditValue; // откат
                // Перемещение каретки в исходное потожение
        int length= Edit1->Text.Length();
        CaretPos= (CaretPos<length)?CaretPos:length;
        Edit1->SelStart= CaretPos;
                // Подсказка
        TPoint P(Edit1->BoundsRect.Right,
                Edit1->BoundsRect.Top+Edit1->ClientRect.Height()/2);
        BalloonHint1->ShowHint(Form1->ClientToScreen(P));
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
     CaretPos= Edit1->SelStart; // Запоминаем положение курсора
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    float x1;
    try
    {
        x1 = StrToFloat(Edit1->Text);
        //...
    }
    catch(const Exception& E)
    {
        ShowMessage("Некорректно заданны исх.данные "+E.Message);
    }
}
//---------------------------------------------------------------------------
Edit и отрицательные числа
2
SatanaXIII
Почетный модератор
Эксперт С++
5796 / 2791 / 385
Регистрация: 01.11.2011
Сообщений: 6,798
Завершенные тесты: 1
28.10.2014, 09:09 15
Цитата Сообщение от krv Посмотреть сообщение
я подозреваю, что внутри этого TryStrToFloat
паскалевская реализация. В ней нет исключений.
0
Нитонисе
10 / 10 / 4
Регистрация: 12.10.2013
Сообщений: 249
28.10.2014, 11:56 16
Цитата Сообщение от UI Посмотреть сообщение
То есть, лишь бы набыдлокодить?
почему сразу "набыдлокодить"? Насколько я понял функция StrToFloatDef всегда заменяет дефолтным значением некорректный ввод, но иногда никакого дефолтного значения и быть не может по логике программы. Например вы делаете калькулятор сложения и у вас два поля для ввода - числа, которые, собственно, нужно сложить. И вот в одно поле вы вводите "2", а во второе "а". В вашей программе ответ получится "2" (если дефолтным указать ноль), что является очевидной глупостью. Более подходящим вариантом видится перехват ввода во втором поле и сигнализация об ошибке. Я в подобных случаях использую структуру try/catch и если в поле введено некорректное значение, то выдаю соответствующее сообщение ShowMessage, устанавливаю фокус на поле, где допущена ошибка и выделяю его содержимое. Мне кажется такое поведение наиболее подходящим и универсальным.
0
SatanaXIII
Почетный модератор
Эксперт С++
5796 / 2791 / 385
Регистрация: 01.11.2011
Сообщений: 6,798
Завершенные тесты: 1
28.10.2014, 12:09 17
Цитата Сообщение от Нитонисе Посмотреть сообщение
Более подходящим вариантом видится перехват ввода во втором поле и сигнализация об ошибке.
Неверно.
Более подходящим является простой анализ строки. И сравнение символов на принадлежность к цифрам. Механизм исключений использовать здесь слишком жирно. Это не значит, что он не сработает. Сработает. Как впрочем и вариант нанять человека, который будет за неверный ввод бить по рукам линейкой.
0
Avazart
Эксперт С++
7909 / 5732 / 566
Регистрация: 10.12.2010
Сообщений: 26,229
Записей в блоге: 17
28.10.2014, 13:17 18
Цитата Сообщение от Нитонисе Посмотреть сообщение
И вот в одно поле вы вводите "2", а во второе "а".
И это не самый спорный вариант, ибо ввод "а" можно запретить, а вот "-" запретить нельзя ибо число может быть отрицательным, но пользователь может ввести "-", но не чисел, что не верно. Именно по этому нужна двойная проверка.
0
Нитонисе
10 / 10 / 4
Регистрация: 12.10.2013
Сообщений: 249
28.10.2014, 19:04 19
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Более подходящим является простой анализ строки.
Это что за анализ? В блоке try при попытке присвоить переменной типа float результат, возвращаемый функцией StrToFloat в принципе анализом можно и назвать.
0
28.10.2014, 19:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.10.2014, 19:04

Определить, есть ли в массиве отрицательные числа
Определить, есть ли в массиве В отрицательные числа. Ответ должен быть «Да» или «Нет».

Как считывать числа из memo или edit?
Уже неделю сижу и пытаюсь понять как это сделать. Все, что можно перепробовал, но считывается...

Преобразование числа из Edit с помощью функции atof
Есть Edit1 в котором записано число, которое мне нужно преобразовать через функцию atof. Мои...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru