Загрузка данных


program ShopInventory;

const
  MAX_ITEMS = 1000;

type
  { Структура для хранения информации о товаре }
  TProduct = record
    Name: string[50];       { Название товара }
    Store: string[50];      { Название магазина }
    Price: real;            { Стоимость в тыс. руб. }
    QtyValue: real;         { Количество }
    QtyUnit: string[10];    { Единица измерения (шт., кг, л) }
  end;

  { Структура для хранения списка товаров }
  TProductList = record
    Items: array[1..MAX_ITEMS] of TProduct;
    Count: integer;
  end;

{ ================= БЛОК ВВОДА С КОНТРОЛЕМ ОШИБОК ================= }

{ Функция для безопасного ввода вещественного числа }
function ReadReal(Prompt: string; MinVal: real): real;
var
  S: string;
  V: real;
  Code: integer;
begin
  repeat
    Write(Prompt);
    Readln(S);
    Val(S, V, Code);
    if (Code <> 0) or (V < MinVal) then
      Writeln('[Ошибка] Введите корректное положительное число!');
  until (Code = 0) and (V >= MinVal);
  ReadReal := V;
end;

{ Функция для безопасного ввода целого числа (например, для меню) }
function ReadInt(Prompt: string; MinVal, MaxVal: integer): integer;
var
  S: string;
  V, Code: integer;
begin
  repeat
    Write(Prompt);
    Readln(S);
    Val(S, V, Code);
    if (Code <> 0) or (V < MinVal) or (V > MaxVal) then
      Writeln('[Ошибка] Введите число от ', MinVal, ' до ', MaxVal, '!');
  until (Code = 0) and (V >= MinVal) and (V <= MaxVal);
  ReadInt := V;
end;

{ ================= БЛОК РАБОТЫ С ФАЙЛОМ ================= }

{ Загрузка данных из текстового файла }
procedure LoadFromFile(var List: TProductList; FileName: string);
var
  F: Text;
begin
  List.Count := 0;
  Assign(F, FileName);
  {$I-} Reset(F); {$I+} { Отключаем автовывод ошибок для ручной проверки }
  
  if IOResult <> 0 then
  begin
    Writeln('Файл "', FileName, '" не найден. Создан новый пустой список.');
    Exit;
  end;

  while not EOF(F) and (List.Count < MAX_ITEMS) do
  begin
    Inc(List.Count);
    Readln(F, List.Items[List.Count].Name);
    Readln(F, List.Items[List.Count].Store);
    Readln(F, List.Items[List.Count].Price);
    Readln(F, List.Items[List.Count].QtyValue);
    Readln(F, List.Items[List.Count].QtyUnit);
  end;
  Close(F);
  Writeln('Данные успешно загружены! (Записей: ', List.Count, ')');
end;

{ Запись данных в текстовый файл }
procedure SaveToFile(const List: TProductList);
var
  F: Text;
  FileName: string;
  i: integer;
begin
  Write('Введите имя файла для сохранения (например, data.txt): ');
  Readln(FileName);
  
  Assign(F, FileName);
  Rewrite(F);
  for i := 1 to List.Count do
  begin
    Writeln(F, List.Items[i].Name);
    Writeln(F, List.Items[i].Store);
    Writeln(F, List.Items[i].Price:0:3);
    Writeln(F, List.Items[i].QtyValue:0:2);
    Writeln(F, List.Items[i].QtyUnit);
  end;
  Close(F);
  Writeln('Список успешно сохранен в файл "', FileName, '".');
end;

{ ================= БЛОК ОБРАБОТКИ ДАННЫХ ================= }

{ Вывод одного товара }
procedure PrintProduct(const P: TProduct);
begin
  Writeln('Товар:    ', P.Name);
  Writeln('Магазин:  ', P.Store);
  Writeln('Цена:     ', P.Price:0:2, ' тыс. руб.');
  Writeln('Наличие:  ', P.QtyValue:0:2, ' ', P.QtyUnit);
  Writeln('-----------------------------------');
end;

{ Вывод всего списка }
procedure PrintList(const List: TProductList);
var
  i: integer;
begin
  if List.Count = 0 then
  begin
    Writeln('Список пуст.');
    Exit;
  end;
  
  Writeln('--- СПИСОК ТОВАРОВ ---');
  for i := 1 to List.Count do
    PrintProduct(List.Items[i]);
end;

{ Добавление нового товара (корректировка списка) }
procedure AddProduct(var List: TProductList);
begin
  if List.Count >= MAX_ITEMS then
  begin
    Writeln('Список заполнен!');
    Exit;
  end;
  
  Inc(List.Count);
  Writeln('--- ДОБАВЛЕНИЕ ТОВАРА ---');
  Write('Название товара: '); Readln(List.Items[List.Count].Name);
  Write('Название магазина: '); Readln(List.Items[List.Count].Store);
  
  List.Items[List.Count].Price := ReadReal('Стоимость (тыс. руб.): ', 0);
  List.Items[List.Count].QtyValue := ReadReal('Количество: ', 0);
  
  Write('Единица измерения (шт, кг, л и т.д.): '); 
  Readln(List.Items[List.Count].QtyUnit);
  
  Writeln('Товар успешно добавлен!');
end;

{ Сортировка пузырьком (по названию или магазину) }
procedure SortList(var List: TProductList; ByName: boolean);
var
  i, j: integer;
  Temp: TProduct;
  NeedSwap: boolean;
begin
  if List.Count < 2 then Exit;

  for i := 1 to List.Count - 1 do
    for j := 1 to List.Count - i do
    begin
      if ByName then
        NeedSwap := (List.Items[j].Name > List.Items[j + 1].Name)
      else
        NeedSwap := (List.Items[j].Store > List.Items[j + 1].Store);

      if NeedSwap then
      begin
        Temp := List.Items[j];
        List.Items[j] := List.Items[j + 1];
        List.Items[j + 1] := Temp;
      end;
    end;
  Writeln('Список успешно отсортирован.');
end;

{ Поиск товара по названию }
procedure SearchByName(const List: TProductList);
var
  SearchQuery: string;
  i: integer;
  Found: boolean;
begin
  Write('Введите название товара для поиска: ');
  Readln(SearchQuery);
  
  Found := False;
  for i := 1 to List.Count do
  begin
    { Используем строгое совпадение. Для нестрогого можно перевести в нижний регистр }
    if List.Items[i].Name = SearchQuery then
    begin
      if not Found then Writeln('--- НАЙДЕННЫЕ ТОВАРЫ ---');
      PrintProduct(List.Items[i]);
      Found := True;
    end;
  end;
  
  if not Found then
    Writeln('Товар с названием "', SearchQuery, '" не найден.');
end;

{ ================= ГЛАВНАЯ ПРОГРАММА ================= }
var
  MainList: TProductList;
  Choice: integer;
  DefaultFileName: string;

begin
  DefaultFileName := 'products.txt';
  
  Writeln('Инициализация программы...');
  LoadFromFile(MainList, DefaultFileName);
  
  repeat
    Writeln;
    Writeln('========== ГЛАВНОЕ МЕНЮ ==========');
    Writeln('1. Показать список товаров');
    Writeln('2. Добавить товар (корректировка)');
    Writeln('3. Сортировка по названию товара');
    Writeln('4. Сортировка по названию магазина');
    Writeln('5. Поиск товара по названию');
    Writeln('6. Сохранить список в файл');
    Writeln('0. Выход из программы');
    Writeln('==================================');
    
    Choice := ReadInt('Выберите действие (0-6): ', 0, 6);
    Writeln;
    
    case Choice of
      1: PrintList(MainList);
      2: AddProduct(MainList);
      3: SortList(MainList, True);  { True = сортировка по названию }
      4: SortList(MainList, False); { False = сортировка по магазину }
      5: SearchByName(MainList);
      6: SaveToFile(MainList);
      0: Writeln('Завершение работы. До свидания!');
    end;
  until Choice = 0;
end.