Pascal ReadLn несколько типов переменных - PullRequest
0 голосов
/ 24 ноября 2011

Моя проблема выглядит следующим образом. Я получил файл с данными (ввод) " текстовый номер с номером " в каждой строке, мне нужно получить данные из него, используя ReadLn (myfile, string, string2, real1 (или double), real2 (или double)); как вы можете видеть в моем коде, представленном ниже, но когда я делаю это с функцией, которую я только что описал, Я получаю ошибку . Мне нужны все данные в отдельной переменной . Мне нужно работать с числами (умножение, сумма), и мне нужно имя и фамилию для выходного файла (результата), где данные будут выглядеть так: «Имя Фамилия номер 1 (из входного файла), умноженная на число 2 (из входного файла)» для каждая строка из входного файла и в последней строке будет «Всего: сумма (все строки (число 1 * число 2))». Единственная проблема, с которой мне нужна помощь - это прочитать данные каждой строки из исходного файла в отдельную переменную.

Объяснение файла:

  • Имя Фамилия NumericValue ( double type) NumericValue ( double type)

    Например: Somedude Hissurname 86,5 9,85

Я всегда получаю сообщение об ошибке при попытке прочитать данные строки следующим образом:

  • ReadLn (filevar (: text), имя (: массив строк [25]), фамилия (: массив строка [25]), числовой1 (: вещественный ), числовой2 (: действительный ));

    Например: ReadLn (данные, имя [], сюр [], метры, цена);

Когда я пытаюсь сделать то же самое, но после изменения числовых значений на целое (также в файле):

Изменения, сделанные в файле:

  • Имя Фамилия NumericValue ( целое число тип) NumericValue ( целое число тип)

    например. Somedude Hissurname 86 9

И программный код выглядит так:

  • ReadLn (filevar (: текст), имя (: массив строк [25]), фамилия (: массив строка [25]), числовой1 (: целое число ), числовой2 (: целое число ));

    Например: ReadLn (данные, имя [], сюр [], метры, цена);

Программа работает почти так, как задумано (numeric1 принимает оба числовых значения, а 2nd остается пустым).

E.g.: name[] = Somedude, sur[] = Hissurname, numeric1 = 86 9, numeric2 = 0

Вот как далеко я продвинулся с моим кодом:

program test;
type    mas = array[1..30] of real;
        mas1 = array[1..30] of string[25];

var name,sur:mas1;
    atl:mas;
    meters,price,total:integer;
    i,p,n       :integer;
    data      :text;
begin
    Assign(data, 'somefile.txt');
    Reset(data);
    ReadLn(data,n);
    for i:=1 to n do
        begin
                  ReadLn(data, name[i], sur[i], meters, price);
                  WriteLn(name[i],meters, price);
        end;
    Close(data);
    ReadLn;
end.

Спасибо заранее. Я делал аналогичные посты ранее, но решение не подходит школьным потребностям (слишком сложным для них -.-) Мне нужно использовать простой способ ReadLn с 4 переменными в нем (или 2 или 3, если я не прав ). В любом случае, прости меня за публикацию одной и той же проблемы дважды.

P.S. Прости меня за вопросы форматирования, орфографии и идеи. Я был довольно сонный. Надеюсь, на этот раз я прояснил ситуацию.

1 Ответ

1 голос
/ 24 ноября 2011

(Отвечая на первый абзац по причине, изложенной Кеном в комментариях к вопросу)

В соответствии со стандартом вы должны это сделать.Процедура ReadLn может принимать переменное количество аргументов (что имеет смысл, если вы можете прочитать значения в эти аргументы).

С двумя компиляторами паскаля, на которых я могу протестировать, эта строка

ReadLn(f, s1, s2, r1, r2);

компилируется нормально (где 'f' - это TextFile, 's1' и 's2' - string s, а 'r1' и 'r2' - Real s).

Сделать это немного сложно.Если вы введете приведенные ниже данные (взятые из вашего предыдущего вопроса ),

Brat Sunbather 5.66 55.4

Delphi завершится с 'Недопустимый числовой ввод (EInOutError) ', и FPC завершится ошибкой с ' Недопустимым вводом (EInOutError) '.Проблема в строковых переменных, которые мы хотим прочитать.Вся строка, которую мы предоставляем, на самом деле является строкой (пробел - это совершенно допустимый символ в строке), поэтому, когда код видит строку как первую переменную для чтения, он читает всю строку в нее.

Следовательно, решение состоит в том, чтобы предоставить специальный символ, который будет отмечать конец строки.Ctrl + Z (ASC dec: 26 hex: 1A) работает для Delphi (я не знаю, что (если вообще что-нибудь) будет работать для FPC или других компиляторов).Таким образом, специально созданный текстовый файл (для Delphi) выглядит так:

2
Brat Sunbather 5.66 55.4
    ↑         ↑    ↑    ↑
   ^Z        ^Z space  eol
Bart Simpson 55.7 45.4 
    ↑       ↑    ↑    ↑
   ^Z      ^Z space  eol

edit: Если у вас нет контроля над тем, как создается входной файл, и вы уверены, что «пробел» является разделителем строковой переменной, вы можете читать строковые переменные символ за символом вцикл, пока вы не прочитаете пробел.Примером может быть что-то вроде этого:

procedure TForm1.Button1Click(Sender: TObject);
var
  f: TextFile;
  fn: string;

  Lines: Integer;
  i: Integer;
  first, last: string;
  R1, R2, Total: Real;

  function ReadName: string;
  var
    c: Char;
  begin
    Result := '';
    repeat
      Read(f, c);
      Result := Result + c;
    until c = ' ';
  end;

begin
  fn := 'data.txt';
  AssignFile(f, fn);
  Reset(f);
  Read(f, Lines);
  Readln(f);
  Total := 0;
  for i := 1 to Lines do begin
    first := ReadName;
    last := ReadName;
    Read(f, R1, R2);

// do whatever necessary with names & numbers
//    showmessage(first + ' ' + last + ' - ' + FloatToStr(R1 * R2));

    Total := Total + R1 * R2;
    Readln(f);
  end;
// do whatever necessary with Total
//  ShowMessage(FloatToStr(Total));

  CloseFile(f);
end;
...