Не компилирует
uses System.Reflection;
begin
var a:=MemberTypes.Event;
end.
хотя если добавить & то работает
Не компилирует
uses System.Reflection;
begin
var a:=MemberTypes.Event;
end.
хотя если добавить & то работает
Последнее исправили. В ближайшем обновлении выйдет
Как заставить процедуру Read работать именно как Read, а не Readln ? Исходная ситуация: пытаюсь в цикле ввести массив записей(5штук). Все элементы одной записи пытаюсь ввести в одну строку при помощи отдельных процедур Read. Делается это для того, чтобы каждый из вводимых элементов записи сразу-же контролировать по определенных критериям. Так вот, собственно проблема - процедура Read(каждая) постоянно срабатывает как Readln - то есть получает вводимое значение и переводит строку ввода на следующую строку экрана. Как мне добиться того, чтобы данная процедура работала в одной строке, как это и должно быть(и как это работает в том же древнем Турбо Паскале)? Если это никак нельзя исправить, то как мне реализовать самому данный функционал(как перегружать подпрограммы - я прочитал примеры).
Параметры системы: Windows 8.10. IDE PascalABC.NET версия 3.10 build 1200. Вот исходный код:
Const Maxx=5;
type MyType = record
Fio : string;
Summa : real;
Kol : integer;
end;
var ArrMyType : array of MyType;
i, j : integer;
Begin
SetLength(ArrMyType, Maxx);
for i:= 0 to Maxx-1 do begin
write(' Введите ФИО: '); read(ArrMyType[i].Fio);
write(' Введите cумму: '); read(ArrMyType[i].Summa);
write(' Введите количество: '); read(ArrMyType[i].Kol);
writeln;
// Здесь еще будет блок обработки каждого
// из вводимых значений полей каждой записи по определенным критериям
end;
writeln;
for i:= 0 to Maxx-1 do begin
write(' ФИО: ', ArrMyType[i].Fio);
write(' Cумма: ', ArrMyType[i].Summa:7:2);
write(' Количество: ', ArrMyType[i].Kol);
writeln;
end;
End.
Также возникает дополнительный баг - со второго элемента теряется ввод переменной ArrMyType[i].Fio - write выдаётся, а процедура ввода на этом элементе совсем не срабатывает…
Кстати, аналогичный код по вводу числового одномерного массива - процедура Read опять таки постоянно перескакивает после ввода значения на следующую строку!
Вот код:
Const Maxx=5;
var ArrM : array of Integer;
i, j : integer;
Begin
SetLength(ArrM, Maxx);
for i:= 0 to Maxx-1 do begin
write(' Введите ', i,'-й элемент: '); read(ArrM[i]);
// Здесь еще будет блок обработки каждого
// из вводимых значений массива по определенным критериям
end;
writeln;
writeln;
for i:= 0 to Maxx-1 do write(i,'. ', ArrM[i],' ');
writeln;
End.
В текущей версии перестал компилироваться такой код (раньше было нормально).
unit My;
interface
type A<T> = class
data: T;
end;
function mka<T>(): A<T>;
implementation
function mka<T>() := new A<T>;
// ^ ошибка, предописание и описание имеют разные типы возвр. значения
end.
Если указывать тип явно, то работает, но не хотелось бы увеличивать код.
А вы когда данные вводите, как ввод завершаете? в смысле каждого отдельного поля. не клавишей ли enter? если ей, то в таком случае вы сами строку переводите, и программа тут ни при чем. и как этот перевод строки повлияет на последующую валидацию, если данные введены и уже записаны в переменной?
любой оператор(процедура) ввода заканчивается тем, что Вы заносите вводимое значение в конкретную переменную, нажав клавишу “ввод”. Но процедуры Read и Readln тем и отличаются, что перевод строки должна вызвать только процедура ReadLn. Вы не понимаете различий между этими двумя процедурами(по аналогии с Write и WriteLn)? Нажав клавишу “ввод”, я всего лишь даю системе знать, что завершил ввод конкретного значения, а не даю команду системе изменить текущую строку на следующую. Понимаете?
Если нет - опишите, как вы реализуете программно(ту задачу, код которой я привел выше) ввод переменных одной записи в одну строку, с переходом к следующей строке только при переходе к следующей записи. Только не надо использовать одну процедуру ReadLn для ввода всех переменных одной записи. Ок?
или напишите код ввода массива из 50 элементов в одну строку.
Кстати, я уже сам реализовал данный функционал для разных типов переменных. Только вот при попытке вызвать “перезагруженную” процедуру Read выскакивает ошибка при выполнении кода: ‘Process is terminated due to StackOverflowException’, хотя при компиляции кода никаких ошибок не выдаёт. Или процедуру Read нельзя “перезагрузить” со своим обработчиком ввода?
Ну я пока так и не понял почему их принципиально вводить одной строкой, какой юзкейс и чем плоха разбивка. А я такие задачи даже в паскале пару лет решаю в формах, ввод в консоли сто лет уже не реализовывал. Там на поле ввода и валидацию можно набросить, и форматировать прям в ней же. А в вебе еще и placeholder’ы есть.
ты не понял, я ввожу их не одной строкой, а хочу, чтобы при вводе данных через Read строка(строка экрана, а не данных) оставалась той-же что и до ввода переменной, а не перескакивала на следующую строку экрана
Вопрос к Админу - почему я не могу “перезагрузить” подпрограмму Read на такую-же со своей реализацией? Ошибка описана на пару постов выше. Спасибо.
Этого сделать невозможно если первой Вы считываете строку. Строка считывается вся - до нажатия Enter, а не до пробела.
Чтобы сделать то, что Вы хотите, надо поступать так: вводить строку, разбивать её на лексемы и затем преобразовывать нужные лексемы к целым и вещественным:
var s := ReadlnString;
var ss := s.ToWords;
ArrMyType[i].Fio := ss[0];
ArrMyType[i].Summa := ss[1].ToReal;
ArrMyType[i].Kol := ss[2].ToInteger;
Этот способ решения - наиболее чистый.
Процедуру Read заставить нельзя - даже не пытайтесь.
могу ли я “перезагрузить” подпрограмму Read, написав эту процедуру со своей реализацией?
Боюсь, что это - расплата за полностью переработанный алгоритм вывода типов в коротких функциях. Напомню, что теперь в их телах допускаются лямбда-выражения - было за что бороться. Вернуть назад, конечно, можно, но не хочется.
Можно ли совместить хорошее в новой и старой версии? Мне кажется, что нет, но глубоко я это не исследовал. Запишите это пока в Issue на Github - пусть повисит.
Давайте использовать правильные термины - “переопределить”. Можете - тогда она перекроет действие стандартной. Но делать я это настоятельно не рекомендую - это весьма сложное мероприятие.
Имейте также в виду, что код, который Вы привели, работает правильно - так как ему и положено - Вы просто неверно его трактуете. То есть, это - НЕ БАГ И НЕ ОШИБКА.
Окей, не так выразился, не в одну строку (не в смысле переменную), а одной строкой (как в тетради пишут), без абзацев. Но я по прежнему не понимаю:
Зачем нужно именно так?
Чем плохо то, что есть сейчас, с разбивкой на разные строки?
Не плохо. Просто Вы считываете в строковую переменную вот тут:
write(' Введите ФИО: '); read(ArrMyType[i].Fio);
и хотите считывать до пробела, а Read считывает до конца строки. Это естественное поведение - Read всё до конца строки считает строкой. После считывания строки надо перейти на следующую строку, поэтому если не заниматься садомазохизмом, то все строки считываются не по Read, а с помощью Readln.
Кроме того - последний ввод:
write(' Введите количество: '); read(ArrMyType[i].Kol);
Вы тут точно хотите ввести это значение и следующий ввод осуществлять с новой строки. Поэтому надо писать Readln:
write(' Введите количество: '); Readln(ArrMyType[i].Kol);
Ошибочка в Aggregate
const
n = 2;
begin
var r := Range(1, 3);
r.Println;
var p := 0;
foreach var x in r do
p += n * x;
Println(p);
var s := r.Aggregate((s, x) -> s + n * x);
Println(s);
end.
выдает
1 2 3
12
11
хотя сумы должны быть равными если убрать умножение, то ошибки нет