Автор |
Сообщение |
Иван Гуру |
|
Задание: вычислить площадь треугольника по трем сторонам (a, b, c). Ввод данных о сторонах представить в виде ввода информации с клавиатуры. При вводе неверной информации (величины меньше нуля, использование текстовой строки) вывести на экран информацию об ошибке. После вычисления величины площади треугольника, вывести ее на экран.
не могу буквы определить, не знаю как. Гугл чет не сильно помог. Либо совсем туплю. |
|
|
|
|
not_available Эксперт Предупреждений : 1
|
|
Код: |
var
a, b, c: real;
p: real;
s: real;
begin
p := (a+b+c)/2;
s := sqrt(p*(p-a)*(p-b)*(p-c));
end; |
|
|
|
|
|
Иван Гуру |
|
not_available писал(а): |
Код: |
var
a, b, c: real;
p: real;
s: real;
begin
p := (a+b+c)/2;
s := sqrt(p*(p-a)*(p-b)*(p-c));
end; |
|
При вводе неверной информации (величины меньше нуля, использование текстовой строки) вывести на экран информацию об ошибке |
|
|
|
|
not_available Эксперт Предупреждений : 1
|
|
Иван писал(а): |
При вводе неверной информации (величины меньше нуля, использование текстовой строки) вывести на экран информацию об ошибке |
это элементарно думаем сами, иначе смысл такого изучения? |
|
|
|
|
Иван Гуру |
|
ну в том то и дело, что все есть акромя как проверить на ввод букв.
так то все работает считает. ругается если числа отрицательные |
|
|
|
|
Evgeny79 Гуру |
|
Похоже надо делать отдельную функцию которая будет проверять введенную строку посимвольно и если попадается символ вне диапазона 0-9 то возвращает ошибку.
if CheckStr(InputLine) then begin {считаем площадь} end
else println("Самый хитрый, да?");
function CheckStr(InputLine:string) :boolean;
var
i,c: integer;
begin
c:= length(InputLine);
result:= true;
for i:=1 to c do
if InputLine[i] <> ['0'..'9'] then begin result:= false; break; end;
//не помню как задать диапазон символов
end;
Лет 10 не смотрел в синий аский экран, синтаксис вообще не помню.
Идея думаю ясна. |
|
|
|
|
Иван Гуру |
|
Evgeny79
Спасибо буду думать
сам с 2002 года не смотрел, вот учится опять пошел, лабораторные делаю))))
Понимаю что истина где то рядом, а вспомнить не могу. |
|
|
|
|
1ddr Гуру Предупреждений : 1
|
|
Читать в строчку и проверять по аски кодам, если все пучком преобразовывать в число? Если есть перехватчик исключений (но чото не нашел), то сразу преобразоывать, если словили исключение, то выводишь ошибку))) |
|
|
|
|
not_available Эксперт Предупреждений : 1
|
|
про символ_детект как-то недоглядел
посимвольная проверка введенной строки S
Код: |
for i := 1 to Length(S) do
if S[i] in ['A'..'z'] then
символ_детект := тру
if not символ_детект then
считаем
else
аазаз, символы ввели)) |
|
|
|
|
|
Иван Гуру |
|
not_available
Не много не понял
как я понял
i присваиваем значение 1, функция Length считает сколько символов в строке далее
если переменная s содержит букву затем ошибка
либо
считаем
может не правильно итзьяснил...... но думаю смысл понятен
Зачем нам переменная s и Length
нельзя просто сделать
writeln;
write('введите сторону A=');
if а in ['A'..'z'] and a <= 0 then write('Данные не верны, попробуйте еще раз..');
else
считаем
тоесть принимаем переменную а, смотрим что это не буква (еси буква просим ввести заново) и не 0 и не отрицательное число идем дальше для приема инфы о сторне б |
|
|
|
|
not_available Эксперт Предупреждений : 1
|
|
это просто пример как проверить любую строковую переменную на символы.
так как у тебя переменная "а" типа плавающая запятая/целое_инт, то как простой вариант - это считывать "а" как строку, проверять ее на символы, а затем конвертировать strtofloat() или strtoint()
в твоем примере "if а in ['A'..'z'] and a <= 0" вызовет исключение, т.к. а = int/float |
|
|
|
|
Evgeny79 Гуру |
|
Код: |
for i := 1 to Length(S) do |
В этом примере на каждом шаге цикла будет выполнятся функция Length, это лишнее время. Лучше перед циклом один раз присвоить переменной ее значение и в цикле уже использовать переменную.
Код: |
Count:= Length(S);
for i := 1 to Count do ..
|
В дельфи есть функция function StrToIntDef(const S: string; Default: Integer): Integer;
она возвращает результатом значение Default если не удалось преобразовать строку в число.
Как раз для твоего примера, указываешь StrToIntDef(s,-1); и проверяешь если результат больше 0 то все ок.
Дальше, если не ввели число то программа пойдет дальше лишь сообщив об ошибке. Предлагаю ввод числа заключить в цикл,
Код: |
WriteLn('введите сторону A=');
a:=-1;//устанавливаем отрицательное число чтобы следующий цикл сработал
while a < 0 do
begin
read(s);//ожидаем ввода
a:= StrToIntDef(s,-1);//пытаемся преобразовать введеную строку в число
if a < 0 then WriteLn('Ошибка! Введите целое число.'); //сообщаем об ошибке
end;
|
Остается только придумать тело функции StrToIntDef |
|
|
|
|
Evgeny79 Гуру |
|
Иван писал(а): |
not_available
Не много не понял
как я понял
i присваиваем значение 1, функция Length считает сколько символов в строке далее
если переменная s содержит букву затем ошибка
либо
считаем
может не правильно итзьяснил...... но думаю смысл понятен
Зачем нам переменная s и Length
|
Строка s это массив из символов, там может быть больше одного символа. Тогда циклом нужно проверить каждый символ.
Код: |
if а in ['A'..'z'] and a <= 0 then write |
Тут если "А" больше 1 символа то будет ошибка
и также т.к. "А" это строка то ее нельзя проверять как число. Несоответствие типов будет. |
|
|
|
|
Evgeny79 Гуру |
|
да, кстати как будет описана переменная так ее read вернет
var
a,b,c: integer;
begin
read(a,b,c); // вводим в одну строку через пробел 5 6 7 (enter) и все ок
end;
Цитата: |
Вводимые данные должны строго соответствовать принятому для них описанию типов. Это значит, что в случае нарушения соответствия возникнут ошибки. Сообщение об ошибке имеет вид:
I/O error XX, где XX - код ошибки. |
можно ловить это исключение и снова повторять ввод.
Что-то мне подсказывает, что препод именно эту реализацию и хочет увидеть |
|
|
|
|
Иван Гуру |
|
как то так да?
Код: |
uses crt;
var chek,a,b,c,p,q: integer;
s: real;
flag: boolean;
begin
{$I-}
flag := false;
q:=2;
clrscr;
writeln('Лабораторная работа №3');
writeln('Выполнил: ');
writeln('Задание: вычислить площадь треугольника по трем сторонам');
writeln;
writeln('Введите стороны треугольника: ');
chek:=0;
repeat
writeln;
write('Сторона A=');
readln(chek);
if IoResult = 0 then flag := true;
if chek <= 0 then writeln('Не корректный ввод, попробуйте еще раз...');
until chek > 0;
a:=chek;
chek:=0;
writeln;
repeat
writeln;
write('Введите сторону B=');
readln(chek);
if IoResult = 0 then flag := true;
if chek <= 0 then write('Не корректный ввод, попробуйте еще раз...');
until chek > 0;
b:=chek;
chek:=0;
write(#13,#10);
repeat
writeln;
write('Введите сторону C=');
readln(chek);
if IoResult = 0 then flag := true;
if chek <= 0 then write('Не корректный ввод, попробуйте еще раз...');
until chek > 0;
c:=chek;
chek:=0;
if (a+b>c) and (a+c>b) and (b+c>a) then
begin
p:=(a+b+c) div 2;
s:=sqrt(p*(p-a)*(p-b)*(p-c));
writeln;
writeln('-------------------------------------------');
writeln;
writeln('Площадь треугольника равна : ',s:3:0);
end
else
writeln('Треугольника не существует ');
writeln;
write('для завершения работы нажмите любую Enter');
readln;
end.
|
|
|
|
|
|
Evgeny79 Гуру |
|
Ввод можно сократить в один цикл for, он не только цифры перебирает
Код: |
var
i: char;
a,b,c,e: integer;
flag: boolean;
begin
...
writeln('Введите стороны треугольника: ');
for i:='A' to 'C' do
begin
flag:= true;
repeat
writeln;
write('Сторона '+i+'=');
readln(e);
if IoResult = 0 then
if e>0 then flag := false;
if flag then writeln('Не корректный ввод, попробуйте еще раз...');
until flag;
case i of
'A': a:=e;
'B': b:=e;
'C': c:=e;
end;
end; // for i:
if (a+b>c) and (a+c>b) and (b+c>a) then
...
|
|
|
|
|
|
kiss06 Эксперт Предупреждений : 3
|
|
кажется была в паскале встроенная функция преобразования строки в число. но собственной проверки на отсутствие букв кажись не избежать, чтоб не нарваться на вылет программы. тут можно просто проверить вводимое на соответствие диапазону кодов чисел по ASCII. короче осуществляем прием данных посимвольно через кейпресс и каждый клик пробиваем. левые нажатия просто в игнор. так будет грамотно. |
|
|
|
|
|