Как открыть текстовый файл, записать туда что-либо дальше, закрыть файл? Пример:
Есть текстовый файл по пути “ПутьКФайлу”. В нём содержится следующий текст:
Текст.
Произошёл вызов подпрограммы ПодпрограммаДля
N
ВФайлПоПути(ПутьКФайлу, ЧтоЗаписать: string)
. Результат:
N = Write:
Текст.ЧтоЗаписать
N = Writeln;
Текст.ЧтоЗаписать
(Новая строка.)
N = Print;
Текст.ЧтоЗаписать
N = Println;
Текст.ЧтоЗаписать
(Новая строка.)
Посмотрите для начала на статичные свойства классов в System.IO
, в частности класса System.IO.File
. Основы ввода-вывода надо знать, а не по первому поводу спрашивать.
Как получить в виде строки весь текст, выведенный в окно консольного приложения?
Без глубокого закапывания в WinAPI консоли - никак. Символы выведенные в консоль в принципе не хранятся в виде строки. Вместо этого там таблица с элементами, хранящими символ + кучу информации типа цвета. Короче это всё принципиально не предназначено для чтения как строки. Сохраняйте то что вывели в своих структурах.
Я хочу иметь возможность удалить или заменить некоторые символы в тексте, выведенном в окно консольного приложения. Если бы можно было легко получить в виде строки весь текст, выведенный в окно консольного приложения, я бы просто изменил строку, выполнил Console.Clear
, вывел строку.
То есть мне нужно при каждом выводе прибавлять к переменной типа string выведенный текст?
Как как, а так реализовывать точно не нужно. Каждое изменение строки создаёт новую строку. Для строк размером с буфер консоли - добавление 1 символа может уже создавать значительную задержку.
Лучше, к примеру, опишите класс-блок текста, хранящий своё положение на экране и методы для изменения текста в нём и т.п.
Прочитайте как использовать external
, затем читайте что значит каждый из типов в описании этой функции.
Как оптимизировать код по преобразованию некоторых символов одной строки в другие символы и записи этих символов в другую строку?
У меня код выглядит следующим образом:
for var i := 1 to Length(ОднаСтрока) do
case Copy(ОднаСтрока, i, 1) of
'Q': ДругаяСтрока += 'T';
'W': ДругаяСтрока += 'Y';
'E': ДругаяСтрока += 'U';
'R': ДругаяСтрока += 'I';
end;
или
loop n do
begin
ДругаяСтрока += ПодпрограммаСCase(Copy(Источник, x, 3));
x += 3;
end;
Используйте или массив (если все кодируемые символы идут подряд в юникоде), или словарь (во всех остальных случаях).
begin
var d := new char[26]; // для всех англ. букв
// заполнение только чтоб пример работал
d.Fill(i->char('A'.Code+i));
d.Shuffle;
d.Println;
foreach var ch in ReadString do
begin
var encoded := if ch in 'A'..'Z' then d[ch.Code-'A'.Code] else ch;
Write(encoded);
end;
end.
А вы в своём коде зачем то сравнивали строки, вместо того чтоб взять 1 символ индексатором, это жесть как не эффективно (и по памяти, и особенно по скорости).
Так нормально?
function encode(s:string; d:Dictionary<char, char>):string;
begin
var sb := System.Text.StringBuilder.Create;
foreach var c in s do if d.Keys.Contains(c) then sb.Append(d[c]);
Result:=sb.ToString;
end;
begin
var d := Dict(KV('e','ç'),KV('щ','l'),KV('i','b'),KV('п','Ü'));
Write(encode(ReadString, d));
end.
Как правильно применить .TryGetValue
в подпрограмме?
d.TryGetValue
. Я пишу без имени переменой, чтоб не привязывать к конкретно вашей реализации. Но .
в начале показывает что это метод, то есть надо вызывать для переменной по точке.
Или вы не понимаете как работать с var
-параметрами?
Как оптимизировать преобразование по трём символам?
loop n do
begin
ДругаяСтрока += ПодпрограммаСCase(Copy(Источник, x, 3));
x += 3;
end;
Так же - словарь. Для строк только через словарь.
И таки не используйте Copy
. Используйте хотя бы срезы.
В коде
loop n do
begin
c := s[НачалоСреза:НачалоСреза + 3];
if d.TryGetValue(c, v) then sb.Append(v + ', ' * Запятых);
НачалоСреза += 3;
end;
должно быть sb.Append
от string
?
sb.Append(v);
sb.Append(', ', Запятых);
Весь смысл StringBuilder
- не выполнять сложения строк, которые затратны.
должно быть sb.Append
от string
?
В смысле?
Я хотел бы считывать значения с клавиатуры без перехода на следующую строку. Для этого я попытался сделать процедуру
procedure Backspace(процедура; значение процедуры (2), если это функция); // Backspace — 1, процедура — 2
begin
var x := Console.CursorLeft;
var y := Console.CursorTop; //сохранение положения курсора
var a := // значение процедуры (2), если это функция
var m: integer;
if (Console.BufferHeight > Console.WindowHeight) then m := Console.LargestWindowWidth - 3 else m := Console.LargestWindowWidth; // расчёт количества символов, которое влезет в окно текущей ширины
var l := a.ToString.Length; // длина введённых данных
x += l;
while (x >= m) do
begin
x -= m;
y += 1; // расчёт положения курсора сразу после ввода
end;
Console.CursorLeft := x;
Console.CursorTop := y; // восстановления положения курсора
end;
При составлении процедуры у меня возник вопрос: как в подпрограмму (1) передать любую подпрограмму ввода (2), чтобы в подпрограмме (1) выполнить подпрограмму ввода (2) и присвоить переменной внутри этой подпрограммы (1) значение функции ввода (2), если подпрограмма ввода (2) является функцией?