Почему при использовании Delphi ReadLn для считывания значений из файла с разделителями табуляцией в ряд переменных, некоторым переменным не присваивается соответствующее значение, когда я прохожу через отладчик?

Т.е.


x, y, z: Integer;
...
ReadLn(fh, x, y, z);
MessageBox(int2Str(y));
...

Только y имеет значение, x и z равны 0 ...

Примечание. Это было отредактировано после полностью верного ответа Мейсона Уиллера.

3
Brendan 7 Авг 2009 в 19:43

4 ответа

Лучший ответ

Это симптом более общей ошибки, в частности, попытки отладить значения неиспользуемых переменных.

Вкратце: По умолчанию компилятор оптимизирует неиспользуемые переменные

Если при поэтапном написании кода вы решите отладить и обнаружите, скажем, что процедура ReadLn правильно считывает переменные, вы можете обнаружить, что значения пусты или 0. Если переменные не используются позже в код - что может быть не так, если вы выполняете отладку по мере написания каждой строки - компилятор, кажется, оптимизирует их.

Я использовал в этом примере ReadLn, поскольку вполне возможно, что вы захотите использовать данные во втором столбце файла csv, и вам придется создавать различные одноразовые переменные, которые не используются. При проверке значений одноразовых переменных вы затем обнаруживаете, что они не содержат того, что вы ожидаете!

В приведенном выше примере вы можете заставить отладчик загружать vlaues, просто «используя» переменные позже в коде, т.е.


x, y, z: Integer;
...
ReadLn(fh, x, y, z);
MessageBox(int2Str(y));
MessageBox(int2Str(x));
MessageBox(int2Str(z));
...

Теперь при наведении указателя мыши также отображаются значения y и z.

1
Brendan 16 Авг 2009 в 09:44

ReadLn? хммм (по памяти) Ожидалось ли по одной строчке для каждой переменной ??? На самом деле не помню ...

0
Fabricio Araujo 7 Авг 2009 в 17:02

Использование ReadLn () в этом примере ненадежно, потому что он будет читать до первого пробела, добавлять его к первому числу, затем ко второму пробелу, добавлять это и т. Д. Вы выполняете ReadLn, таким образом, все, что выходит за рамки третье целое число в этой строке игнорируется! А отсутствующие значения по умолчанию равны нулю.

Если ваши числа начинаются с пробелов, X будет пробелом, т.е. нулем. Y будет первым числом до разделителя табуляции. Z будет вторым пробелом перед вторым числом, поэтому по умолчанию ноль.

Честно говоря, я использую ReadLn () только для чтения всей строки из текстового файла. С типами, разделенными табуляцией, я обычно использую всевозможные другие методы, включая использование строкового списка.

1
Wim ten Brink 16 Авг 2009 в 10:16

Readln будет анализировать ввод как можно лучше для типов переменных, которые вы ему даете, но если ваш первый (имя) является строкой, он будет читать все до разрыва строки. Если вы хотите загрузить файл с разделителями табуляции, я бы использовал TStringList и установил символ-разделитель на # 9.

5
Mason Wheeler 7 Авг 2009 в 17:48