С Новым годом! Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
0 / 0 / 1
Регистрация: 22.05.2013
Сообщений: 120
1

Проблема с записью в файл

16.01.2020, 08:26. Показов 1536. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем доброго дня. Решаю задачку про автопарк и возникает проблема, что код отрабатывает, но в файл запись данных не происходит. Коротко в двух словах - из файла с входными данными (input.txt) должны удаляться строки где есть слово out и вписываться строки где есть слово in и когда достигается слово delivery то получившиеся данные записываются в файл output.txt
когда ввожу неверные данные то в файл записывается слово ERROR, как и должно быть, а вот если ввожу корректные данные то файл так и остается пустым. Подскажите, пожалуйста, что упущено?
Pascal
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
var CountCar,i:integer;
 
NameCar,NameCarHist:array[0..100000] of string;
 
finput,s,foutput,action,car: string;
 
f,f1:textFile;
 
 
l,l1:boolean;
 
 
begin
 
l:=true;
 
//============ ВХОДНЫЕ ДАННЫЕ ======
 
finput:='c:\1\4\input.txt'; //полный путь до файла с входными данными
 
foutput:='c:\1\4\output.txt'; // Полный путь до файла с итоговыми данными
 
AssignFile(f, finput); // Создаем курсор на файл
 
AssignFile(f1, foutput); // Создаем курсор на файл аут
 
Reset(f); //Открываем файл
 
Readln(f,s); //Читаем первую строку
 
CountCar:=StrToInt(s);   //количество машин в парке уже
 
//заполним базу машинами (точнее базу и историю базы
 
for i:= 0 to CountCar - 1 do 
  begin
 
    Readln(f,s);
 
    NameCar[i]:= s;
 
    NameCarHist[i]:=s;
 
  end;
 
//изначальный массив сохранен.
 
 
while (l) do
 
begin
 
  Readln(f,s);
 
  //если конец списка, выйдем из цикла
 
  if s='delivery' then
 
    l:=false
 
  else
 
    //если не конец списка, то работаем
 
    begin
 
      //какое действие: in\out
 
      action:=copy(s,1,pos(' ',s)-1);
 
      //удалил действие
 
      s:=trim(copy(s,pos(' ',s),length(s)-pos(' ',s)+1));
 
      //возьмем тачку
 
      car:= copy(s,1,length(s));
 
      //разобрали строку
 
 
      if action = 'out' then
 
      //выезжаем
 
      begin
 
        l1:=false;
 
        //берем основной массив и ищем эту машину
 
        for i:=0 to CountCar do
 
          if  NameCar[i]=car then
 
            begin
 
              //просто обнулим, если она была, и запомним что мы удалили её(флаг)
 
              NameCar[i]:='';
 
              l1:=true;
 
            end;
 
        //если флаг не поменялся - машины нет в парке - ошибка
 
        if l1=false    then
 
          begin
 
            AssignFile(f1, foutput);
 
            Rewrite(f1);
 
            Writeln(f1,'ERROR');
 
            CloseFile(f1);
 
          end;
 
      end
 
      else
 
        begin
 
          l1:=true;
 
          //мы заезжаем
 
          //так же проверка в основном массиве, на присутствие машины
 
          for i:=0 to CountCar do
 
            if NameCar[i]=car then
 
              //если есть в списке, то ошибка въезда
 
              begin
 
                AssignFile(f1, foutput);
 
                Rewrite(f1);
 
                Writeln(f1,'ERROR');
 
                CloseFile(f1);
 
                l1:=false;
 
              end;
 
        //флаг на месте - машины там нет
 
        if l1=true then
 
          begin
 
            l1:=false;
 
            //машины нет в парке, проверим, а была ли?
 
            for i:=0 to CountCar do
 
              if NameCarHist[i]=car then
 
                begin
 
                  //если была, ставим на то же место, запомним что тачку поставили
 
                  NameCar[i]:=car;
 
                  l1:=true;
 
                end;
 
            //если тачки нет и небыло там, ставим в последнее +1 место тачку + в историю, что приехали и заняли это место
 
            if l1=false then
 
              begin
 
                CountCar:=CountCar+1;
 
                NameCar[CountCar]:=car;
 
                NameCarHist[CountCar]:=car;
 
              end;
 
          end;
 
        end;
 
    end;
 
 
 
end;
 
//вывод в файл, если не еррор
 
//выводим в файл все не пустые места, чтобы небыло дыр в отчете.
 
if l=true then
 
  begin
 
    AssignFile(f1, foutput);
 
    Append(f1);
 
  for i:=0 to CountCar do
 
    if NameCar[i]<>'' then
 
      Writeln(f1,NameCar[i]);
 
    CloseFile(f1);
 
  end;
 
end.
Добавлено через 6 минут
забыл добавить. пример входных данных:
5
27
56
28
77
48
out 27
out 77
in 44
out 28
delivery

соответственно на выходе должно получиться:
56
48
44

Добавлено через 37 минут
и в 212 строке Rewrite, а не Append.
Но это не решение моей проблемы, всё равно не вижу где я еще что-то упустил
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.01.2020, 08:26
Ответы с готовыми решениями:

Проблема с записью в файл
Не умею работать с выводом в файл в С++, как сделать чтобы записывало результат в txt, это...

Проблема с записью в файл
Коллеги, подскажите в чем проблема. Вот скрипт,для записи данных в файл. В результате его роботы...

Проблема с записью в файл
try{ BufferedReader br = new BufferedReader(new FileReader(fileIn)); FileWriter fw = new...

Проблема с записью в dbf файл
программа пишет в dbf файл только на машине на которой собственно и написана прога, на всех...

17
5084 / 2655 / 2350
Регистрация: 10.12.2014
Сообщений: 10,048
16.01.2020, 08:43 2
PacificABCNET, приведите полное нормальное задание, а не „коротко в двух словах“!
… и что-за фетиш писать код программы через строку?
0
0 / 0 / 1
Регистрация: 22.05.2013
Сообщений: 120
16.01.2020, 08:50  [ТС] 3
вот задание

Кадеты в увольнении ходили в кино смотреть детективный фильм. В основе сюжета лежит история проникновения солдат вражеского войска на территорию контрольно-технического пункта (КТП) автопарка военной части и похищение оружия. Кадеты Петров и Пупкин достаточно практичные и считают, что ошибок лучше не допускать, чем их потом исправлять, поэтому они решили найти ответ на вопрос: как возможно было избежать проникновения врага и хищения оружия. Они внимательно изучили обязанности дежурного по автопарку, согласно которым, он следит за сохранностью имущества и военной техники, находящейся под его охраной. Для этого он фиксирует все въезжающие и выезжающие автомобили. Машины, которые выезжали и въехали обратно в автопарк - встают на свои прежние места (если автомобиль въехал впервые, то он встает в конец ряда - место, не принадлежащее никакому из выехавших автомобилей).
В ходе дежурства ведется журнал передвижения транспортного средства, где фиксируются номера въезжающих и выезжающих автомобилей. По истечению дежурства необходимо подать рапорт со сведениями о находящихся в автопарке автомобилях. Кадеты решили, что если автоматизировать этот процесс, то неприятностей, описанных в сюжете, можно избежать. Напишите программу учета въезда/выезда автомобилей. При вводе неверной комбинации Номер автомобиля + команда (при попытке выезда автомобиля, отсутствующего в автопарке либо при въезде автомобиля уже находящегося в автопарке) программа выводит сообщение об ошибке ERROR. Работа автопарка прекращается, начинается сверка автомобилей, перепроверка журнала.

Входные данные:
в первой строке вводится натуральное число N – количество автомобилей в автопарке (0< N ≤ 106)
в каждой из N последующих строк подаются номера автомобилей, находящихся в автопарке; далее в последующих n строках вводится код команды и через пробел номер автомобиля, выполняющего данную команду (код команд in- въезд, out - выезд, delivery – сдача наряда), ввод заканчивается командой delivery, но количество команд не превышает 105. Номера автомобилей - натуральные числа, не превышающие 106.

Выходные данные:
Программа выводит перечень номеров автомобилей, находящихся в автопарке на момент окончания дежурства курсанта.
0
Почетный модератор
64304 / 47600 / 32742
Регистрация: 18.05.2008
Сообщений: 115,181
16.01.2020, 09:21 4
106 это 106
105 это 105 ??
0
0 / 0 / 1
Регистрация: 22.05.2013
Сообщений: 120
16.01.2020, 09:24  [ТС] 5
да, извиняюсь, забыл это поправить при копировании задания
0
5084 / 2655 / 2350
Регистрация: 10.12.2014
Сообщений: 10,048
16.01.2020, 09:37 6
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
procedure error;
begin
  'ERROR'.Println;
  halt;
end;
 
begin
  Reset(input, 'input.txt');
  Rewrite(output, 'output.txt');
  var count := ReadLnInteger;
  var list := New List<integer>;
  for var i := 1 to count do list.Add(ReadLnInteger);
  repeat
    var s := ReadLnString;
    if s.IndexOf('delivery') = 0 then Break;
    var n := StrToInt(s.ToWords[1]);
    case s.ToWords[0] of
      'in' : if list.Contains(n) then error else list.Add(n);
      'out' : if not list.Contains(n) then error else list.Remove(n);
    end;
  until False;
  list.Println;
end.
Если нужно, чтобы список был построчный, то последний Println заменить на PrintLines
1
0 / 0 / 1
Регистрация: 22.05.2013
Сообщений: 120
16.01.2020, 09:44  [ТС] 7
да, работает, но если ввести данные, которые вызывают ошибку, то в файл ничего не записывается.

Вот при таких данных должно появиться сообщение ERROR, но его в файле нет
3
27
56
28
in 89
out 77
delivery

Как исправить?
0
5084 / 2655 / 2350
Регистрация: 10.12.2014
Сообщений: 10,048
16.01.2020, 09:52 8
Лучший ответ Сообщение было отмечено PacificABCNET как решение

Решение

Вывод не проверял на файлах…
Вот так с закрытием:
Pascal
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
procedure error;
begin
  'ERROR'.Println;
  Close(output);
  halt;
end;
 
begin
  Reset(input, 'input.txt');
  Rewrite(output, 'output.txt');
  var count := ReadLnInteger;
  var list := New List<integer>;
  for var i := 1 to count do list.Add(ReadLnInteger);
  repeat
    var s := ReadLnString;
    if s.IndexOf('delivery') = 0 then Break;
    var n := StrToInt(s.ToWords[1]);
    case s.ToWords[0] of
      'in' : if list.Contains(n) then error else list.Add(n);
      'out' : if not list.Contains(n) then error else list.Remove(n);
    end;
  until False;
  list.Println;
  Close(output);
end.
2
0 / 0 / 1
Регистрация: 22.05.2013
Сообщений: 120
16.01.2020, 10:00  [ТС] 9
все работает, спасибо большое
0
Status 418
Эксперт Python
4580 / 2348 / 601
Регистрация: 26.11.2017
Сообщений: 5,264
Записей в блоге: 3
16.01.2020, 19:18 10
при N = 106, интересно сколько придется ждать пока программа завершится?!
1
3049 / 1668 / 656
Регистрация: 19.03.2019
Сообщений: 5,370
17.01.2020, 10:12 11
Цитата Сообщение от eaa Посмотреть сообщение
при N = 106, интересно сколько придется ждать пока программа завершится?!
могу проверить
0
5084 / 2655 / 2350
Регистрация: 10.12.2014
Сообщений: 10,048
17.01.2020, 10:26 12
Не так уж и долго…
Только жалко бедного дежурного по автопарку.
Если, к примеру, на проезд одного автомобиля будет затрачено всего 5 секунд (и столько времени на отметку in/out номер авто), то на это может уйти до шести дней чистого времени (без сна, обеда и отлучек в туалет ;–)

P.S. А в моей программе ошибка!
Не учтено, что автомобиль при повторном въезде должен попасть в уже зарезервированное под него место…
Но, как тогда программа впишется в установленные ограничения по памяти/времени?
0
3049 / 1668 / 656
Регистрация: 19.03.2019
Сообщений: 5,370
17.01.2020, 10:59 13
Цитата Сообщение от JuriiMW Посмотреть сообщение
P.S. А в моей программе ошибка!
Не учтено, что автомобиль при повторном въезде должен попасть в уже зарезервированное под него место…
А что имеется в виду?
я тестировал код, ошибок не увидел.
0
Status 418
Эксперт Python
4580 / 2348 / 601
Регистрация: 26.11.2017
Сообщений: 5,264
Записей в блоге: 3
17.01.2020, 11:39 14
Цитата Сообщение от JuriiMW Посмотреть сообщение
Не так уж и долго…
Перечитал задачу.
Сложность O(n*m) оказывается, думал O(n^2).
n <= 106
m <= 105

5 секунд выполняется в среднем, все равно долго
0
5084 / 2655 / 2350
Регистрация: 10.12.2014
Сообщений: 10,048
17.01.2020, 11:47 15
mr-Crocodile, я вот про это:
Цитата Сообщение от PacificABCNET Посмотреть сообщение
Машины, которые выезжали и въехали обратно в автопарк - встают на свои прежние места (если автомобиль въехал впервые, то он встает в конец ряда - место, не принадлежащее никакому из выехавших автомобилей).
Т.е. «вычёркивание» не подходит, необходимо использовать список типа <integer,boolean>, чтобы контролировать присутствие автомобиля и не менялось его местоположение в списке.
0
3049 / 1668 / 656
Регистрация: 19.03.2019
Сообщений: 5,370
17.01.2020, 13:29 16
Цитата Сообщение от JuriiMW Посмотреть сообщение
чтобы контролировать присутствие автомобиля и не менялось его местоположение в списке.
так нет же такого требования в условиях задачи.
да и по логике - какая разница, в каком порядке выводятся номера? Это ни на что не влияет.

Цитата Сообщение от JuriiMW Посмотреть сообщение
Т.е. «вычёркивание» не подходит, необходимо использовать список типа <integer,boolean>

это было бы полезно в плане скорости - присвоить true/false явно быстрее, чем удалить ссылку из списка.
0
Status 418
Эксперт Python
4580 / 2348 / 601
Регистрация: 26.11.2017
Сообщений: 5,264
Записей в блоге: 3
17.01.2020, 15:12 17
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
begin
  Milliseconds;
  var n := 1000000; //количество номеров
  var m := 10000; //количество запросов
  
  var a := n.Times.ToList; // 4.8 секунд в среднем
  var a := n.Times.ToHashSet; // 0.04 секунды в среднем
  
  loop m do
  begin
    var x := Random(100000);
    if a.Contains(x) then a.Add(x);
    var y := Random(100000);
    if a.Contains(y) then a.Remove(y);
  end;
  Println(MillisecondsDelta / 1000);
end.
Для проверки использовать HashSet, для для хранения использовать List.
List.Add за O(1) выполняется.
И правильно нужно взять что то типа этого List<(integer, boolean)>
1
2351 / 1454 / 526
Регистрация: 07.04.2017
Сообщений: 4,789
17.01.2020, 16:09 18
Вообще что надо было сделать в первую очередь раз нужна производительность:
1. Создавая List - в конструктор передавать размер. А то его внутренний буфер постоянно пересоздаётся при добавлении элементов.
2. List.Remove возвращает false если элемент не найден, так что можно избавится от 1 .Contains

Что насчёт сейчас - предлагаю попробовать рядом со списком так же вести словарь, у которого ключи - номера, а значения - индексы в списке. Это позволит и быстрее проверять существование номера в списке, и быстрее находить, у какого элемента надо переключить флаг.

Вот только у обычных кортежей - элементы неизменяемые. Можно написать свой класс, но лучше использовать ValueTuple. Так, кроме всего прочего, должно быть ещё и быстрее.
Pascal
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
57
58
59
60
61
62
63
64
procedure error;
begin
  'ERROR'.Println;
  output.Close;
  Halt;
end;
 
function VT<T1,T2>(a: T1; b: T2) :=
System.ValueTuple.Create(a,b);
 
begin
//  Reset(input, 'input.txt');
  Rewrite(output, 'output.txt');
  
  var count := ReadlnInteger;
  
  var list := new List<System.ValueTuple<integer,boolean>>(count + count div 2);
  var d := new Dictionary<integer, integer>(list.Capacity);
  
  loop count do
  begin
    var n := ReadlnInteger;
    d.Add(n, list.Count);
    list.Add(VT(n, true));
  end;
  
  repeat
    var s := ReadLnString;
    
    // .StartsWith быстрее .IndexOf, потому что проверяет только начало строки
    if s.StartsWith('delivery') then break;
    
    var ind := s.IndexOf(' ');
    var n := s.Substring(ind+1).ToInteger;
    
    var l_ind: integer;
    var in_park := d.TryGetValue(n, l_ind);
    
    // вообще об этом не сказано, наверное можно тоже .StartsWith('in')
    case s.Remove(ind) of
      
      'in':
      if not in_park then
      begin
        d.Add(n, list.Count);
        list.Add(VT(n,true))
      end else
      if list[l_ind].Item2 then
        error else
        list[l_ind].Item2 := true;
      
      'out':
      if not in_park then
        error else
        list[l_ind].Item2 := false;
      
      else error;
    end;
    
  until false;
  
  list.Where(t->t.Item2).Select(t->t.Item1).Println;
  output.Close;
end.
1
17.01.2020, 16:09
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.01.2020, 16:09
Помогаю со студенческими работами здесь

Проблема с записью в файл, путь которого находится в TextBox
Дело в том что я хотел записать текст в файл, но так чтобы путь он брал из тхтбокса. Пробывал:...

Проблема с записью
Всем привет, есть микрофон bm-800 с фантомным питанием и внешней звуковухой. Есть трудности при...

Проблема с записью в бд
Есть запрос, $quer = mysql_query(&quot;SELECT * FROM $userstable&quot;); $nu = mysql_num_rows($quer); ...

Проблема с записью Даты
Иногда, записывая данные в таблицы при помощи PL/SQL происходит искаженное запоминание даты: вместо...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru