Новые сообщения · Правила  
Страница 1 из 11
Модератор форума: Berestovskiy 
Форум ПРОГРАММИСТОВ » ПРОГРАММИРОВАНИЕ » Паскаль » Прикол от admin(a)
Прикол от admin(a)
Предлагаю развлечение для Программистов (Паскаль). Вот вам скромненький фрагмент програмки. Все просто и ясно, более того в пределах правил. Запускаем, вводим а (целое как следует из описания), просят ввести символ Y или N (или любой другой как вы понимаете). Вводим символ, enter (как положено), пытаемся вывести результат на экран. Но нет, не выводит. Убедитесь сами. ПОЧЕМУ? biggrin Обсудим.

uses crt;
var a:integer;
d:char;
begin
clrscr;
read(a);
writeln('Y/N');
readln(d);
writeln('d=',d);
readkey;
end.

1 | Автор: admin | 2008-03-04, 18:27   |  Репутация: [ + 21 ]
Хм... Сразу я вообще не понял "пытаемся вывести результат на экран. Но нет, не выводит",
но протестировав слегка отшатнулся на стуле)) В этом отрезке "readln(d);" после разных вариаций не обнаружилось действия... К примеру, заменив "readln(d);" на "read(d);", задержки строки не произошло 0_о... Потом рассмотрев ввод символа понял, что что-то не так в "read(a);" ... Может это действие забивает ячейку в памяти?))) Даже не знаю... Просветите что ли:D


я все понимаю...
2 | Автор: flin | 2008-03-04, 20:43   |  Репутация: [ + 8 ]


я все понимаю...
2 | Автор: flin | 2008-03-04, 20:43   |  Репутация: [ + 8 ]
Пока ничего не сообщу, может кто додумается. Попробуйте найти решение проблемы (от противного что-ли). Кой-какие мысли у вас в правильном направлении. Но какова задачка, а?
3 | Автор: admin | 2008-03-04, 20:51   |  Репутация: [ + 21 ]
здесь явно что-то не так с read(a), если убрать этот оператор, то всё прекрасно работает и d выводится на экран. ещё одна странность, которую я заметил: если оператор writeln('d=',d) заменить на write('d=',d)(при этом не менять остальной текст программы), то на экран выводится "d=" и при этом курсор перемещается в начало строки(под символ "d"), но само значение d не выводится...не знаю что и думать...
4 | Автор: hidden | 2008-03-05, 15:54   |  Репутация: [ + 0 ]
так и есть .. :'(, но почему и что делать, и как дальше жить, ведь подобное сочетание можно найти почти в любой программе.
5 | Автор: admin | 2008-03-05, 16:04   |  Репутация: [ + 21 ]
Жаль, что никто не может найти правильный ответ и решение проблемы. Начинаю скучать wink
6 | Автор: admin | 2008-03-10, 15:29   |  Репутация: [ + 21 ]
6 | Автор: admin | 2008-03-10, 15:29   |  Репутация: [ + 21 ]
Интересная проблема) Сначала подумал что символ d просто не читается по какой-то причине, но легко убедиться что это не так. Присваиваем ему какое-то значение с самого начала программы. Выводим и видим пустое место. Значит мы читаем что-то левое, и скорее всего это символ «конец строки»... Оператор readln, ну как я понял =), читает символ не с данной строки, а с последующей. Как следствие туда попадает «конец строки». Решение простое, прочитать сначала этот символ, а потом еще 1. К сожалению не зная как это сделать я просто перед ним дописал еще read(d). К моему удивлению результат роботы программы совсем не изменился. Воспользовавшись методом научного тыка дописал еще read(d) и о чудо, все заработало =)
Думаю что моя идея почему оно не работало верна где-то на половину)
Вот собственно рабочий код:
program NoName;
uses crt;
var
a:integer;
d:char;
Begin
clrscr;
read(a);
writeln('Y/N');
read(d);read(d);
readln(d);
writeln('d=',d);
readkey;
End.


Насколько проще была бы жизнь если бы она была в исходниках
7 | Автор: LofD | 2008-03-11, 15:08   |  Репутация: [ + 14 ]
Умозаключения не лишены здравого смысла. Не лишены. Но как грубо исполнено. Впечатляет read(d);read(d); Особенно, если б кому-то пришлось такую прожку продавать. Хотя по своему и красиво. Давайте всегда и везде все писать по два раза, на всякий случай. Я думаю, вы найдете более элегантное решение проблемы, которую вы хорошо почувствовали.
8 | Автор: admin | 2008-03-11, 18:29   |  Репутация: [ + 21 ]
Есть другой вариант, но нельзя сказать, что намного умнее предыдущего. Место того чтобы читать эти символы их можно просто перепрыгнуть. Воспользоваться оператором readln; вместо двух read(d) … .
program NoName;
uses crt;
var
a:integer;
d:char;
Begin
clrscr;
read(a);
writeln('Y/N');
readln;
readln(d);
writeln('d=',d);
readkey;
End.


Насколько проще была бы жизнь если бы она была в исходниках
9 | Автор: LofD | 2008-03-11, 18:50   |  Репутация: [ + 14 ]
И все-таки это уже лучше и почти совсем то что требуется, осталось додумать совсем чуть-чуть. А там и понимание проблемы придет.
10 | Автор: admin | 2008-03-11, 18:59   |  Репутация: [ + 21 ]
Quote (hidden)
если оператор writeln('d=',d) заменить на write('d=',d)(при этом не менять остальной текст программы), то на экран выводится "d=" и при этом курсор перемещается в начало строки(под символ "d"), но само значение d не выводится...

По-моему d выводиться, это оно и двигает курсор в начало строки O_o. Попробовал написать writeln('12345',d,'ABC') (Не меняя остальную программу) и получил "ABC45"
А если написать writeln ('12345','ABC') то естественно получим "12345ABC";


Насколько проще была бы жизнь если бы она была в исходниках
11 | Автор: LofD | 2008-03-11, 19:18   |  Репутация: [ + 14 ]
Ну тем самым вы подтвердили то о чем говорили раньше, не более.
12 | Автор: admin | 2008-03-11, 19:25   |  Репутация: [ + 21 ]
Получилось!… вроде как. Для того чтобы избавиться от всех ненужных нам символов после чтения a, нужно закрыть и открыть файл. Тогда в нем не будет никаких знаков пробела переноса строки и т.п. Вот как это выглядит. Возможно, работа с файлом тут насовсем корректно описана. =)

uses crt;
var
a:integer;
d:char;
Begin
clrscr;
read(a);
writeln('Y/N');
close(input);
reset(input);
readln(d);
writeln('d=',d);
readkey;
End.


Насколько проще была бы жизнь если бы она была в исходниках
13 | Автор: LofD | 2008-03-11, 19:52 | Изменено: LofD - Вт, 2008-03-11, 19:52   |  Репутация: [ + 14 ]


Насколько проще была бы жизнь если бы она была в исходниках
13 | Автор: LofD | 2008-03-11, 19:52 | Изменено: LofD - Вт, 2008-03-11, 19:52   |  Репутация: [ + 14 ]
Вам приз за оригинальность! Но это не более чем просто оригинальное решение. Можно еще винду переставить biggrin Или комп в другое место. Но рейтинг я вам повысил! Есть другое простое решение, которое и открывает на все сто причину проблемы!
14 | Автор: admin | 2008-03-11, 20:07   |  Репутация: [ + 21 ]
Ну я даже не знаю... Есть два символа которые нужно как-то обойти... Ну можно еще сделать вемсто readln readkey... но это не решит проблему. =\
uses crt;
var
a:integer;
d:char;
Begin
clrscr;
read(a);
writeln('Y/N');
d=readkey;
writeln('d=',d);
readkey;
End.


Насколько проще была бы жизнь если бы она была в исходниках
15 | Автор: LofD | 2008-03-11, 21:14 | Изменено: LofD - Вт, 2008-03-11, 21:15   |  Репутация: [ + 14 ]
Еще проще! Но ваша изобретательность впечатляет!
16 | Автор: admin | 2008-03-11, 21:16   |  Репутация: [ + 21 ]
Место первого read(a) написать readln(a) =\ Но я так понял что этот вариант не рассматривается?

Насколько проще была бы жизнь если бы она была в исходниках
17 | Автор: LofD | 2008-03-11, 21:40   |  Репутация: [ + 14 ]
Как раз это и есть простейшее решение проблемы. Данные вводятся через буфер. И только оттуда считываются процедурами ввода. Занесение в буфер - по нажатию Enter вместе с кодов #13#10 Read в отличие от Readln не очищает буфер. Из-за этого следующий ввод выполняется с места на котором закончился предыдущий - с символа конца строки. Readln - решение всех проблем. Вам повышаем уровень репутации!
18 | Автор: admin | 2008-03-11, 21:50   |  Репутация: [ + 21 ]
Форум ПРОГРАММИСТОВ » ПРОГРАММИРОВАНИЕ » Паскаль » Прикол от admin(a)
Страница 1 из 11
Поиск: