Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];
ВнизЧтение данных из текстового файла Найти похожие ветки
← →
Andrew_Rostov (2004-04-28 18:52) [0]Есть тесктовый файл, содержащий строки с числами (вида 23.34335). Числа разделены пробелами. Задача - занести содержимое файла в массив.
Т.е. прочитать одну строку до символа перевода каретки #10#13 и разместить элементы в массив (предварительно провернув StrToFloat).
Основная неприятность в данный момент - разбиение строки на отдельные числа - может есть встроенная функция (или прийдется возиться с анализом каждого символа поученной строки?).
Пока докопался до:
var
File_2D:TextFile;
procedure LoadFrom_2D(FileName: string);
var
File_String:string;
begin
AssignFile(File_2D,FileName);
Reset(File_2D);
readln(File_2D,File_String);
//а вот тут нужно File_String порезать на кусочки :)
CloseFile(File_2D);
end;
← →
Vit@ly © (2004-04-28 20:55) [1]Требуется уточнение, известно ли количество чисел в строке, одинаково ли оно? В чем собсно смысл строки?
← →
Andrew_Rostov (2004-04-28 21:22) [2]Можно считать, что кол-во чисел в строке задано пользователем.
Смысл строки - "матрица, растянутая в строку", т.е. из этой строки нужно выделить числа и восстановить матрицу.
Основной вопрос - как наименьшими затратами "распотрошить строку". Вручную можно в цикле анализировать каждый символ до появления конца строки, а по ходу дела заносить символы в буфер и при появлении пробела делать StrToFloat("буфер"), но что-то сдается мне должно быть стандартное решение...
← →
Jack128 © (2004-04-28 21:39) [3]Примерно так, я думаю
type
TDoubleArray = array of Double;
procedure ParseDoubleList(const DoubleString: string; out DoubleArray: TDoubleArray);
var
StartChar: PChar;
EndChar: PChar;
begin
if (DoubleString = "") then Exit;
StartChar := @DoubleString[1];
while (ord(StartChar^) <= 32) and (StartChar^ <> #0) do
inc(StartChar);
while StartChar^ <> #0 do
begin
EndChar := StartChar;
while (ord(EndChar^) > 32) and (EndChar^ <> #0) do
inc(EndChar);
dec(EndChar);
SetLength(DoubleArray, Length(DoubleArray) + 1);
DoubleArray[High(DoubleArray)] := StrToFloat(copy(StartChar, 1, Integer(EndChar - StartChar + 1)));
StartChar := PChar(EndChar + 1);
while (ord(StartChar^) <= 32) and (StartChar^ <> #0) do
inc(StartChar);
end;
end;
← →
Vit@ly © (2004-04-28 21:44) [4]Если строки не волнуют, то
procedure ReadFromFile;
Var f: text;
a: real; //или массив Array []
begin
Assign(f, "1111.txt");
Reset(F);
While Not EOF(F) do
begin
Read(f, a);
//здесь разберись со строками и столбцаи, никакого парсинга не потребуется
//
end;
← →
TButton © (2004-04-28 22:25) [5]ну такая есть мысль
делаешь стринглист - буфер.
заменяешь пробелы в строке с чилами запятыми. присваиваешь результат буфер.Commatext и получаешь строку рабитую на... на как надо вобщем =)
← →
Miwa © (2004-04-28 22:29) [6]Прикольно... Александр Панов схожий вопросс задавал в "Потрепаться" пару дней назад. Правда, для него была критична скорость. Вообщем, если уж надо ооооочень крутой алгоритм - поищи в "Потрепаться".
← →
Anatoly Podgoretsky © (2004-04-28 22:37) [7]TButton © (28.04.04 22:25) [5]
Заменять не надо, пробелы являются стандартными разделителями, но проще читать построчно с помощью ReadLn и в Commatext, далее дело техники. Даже количество элементов матрицы знать необязательно в этом случае. Массив для данных динамический двухмерны. Уложиться можно в десяток строк
← →
TButton © (2004-04-28 22:46) [8]>Заменять не надо...
честно - не знал
← →
Юрий Зотов © (2004-04-28 23:15) [9]Господа прогораммисты Delphi! Всякие там классы, парсинг строк и прочие навороты - все это, конечно, замечательно. Но было бы очень неплохо помнить, что старый добрый Паскаль пока еще никто не отменял, и что в первую очередь именно программисту на Delphi следовало бы его знать. И не стрелять из пушки по воробьям.
Поскольку "кол-во чисел в строке задано пользователем" (см. [2]), то никакой проблемы на самом деле не существует, и не надо ее выдумывать. Все делается с помощью самых обыкновенных Read и ReadLn. Нужно всего лишь написать простейший цикл for внутри простейшего цикла while, а это - упражнение для школьников. Подсказку см. в [4].
← →
Германн © (2004-04-29 03:09) [10]Имхо, даже Юрий Зотов © (28.04.04 23:15) [9] - слишком наворочен. (Хотя этот ответ - самый полный!).
Скорее всего достаточно Readln(F,v1,v2...vn), где n - кол-во "чисел в строке заданное пользователем". А вместо v1...vn можно подставить нужные элементы массива.
← →
Fay © (2004-04-29 04:02) [11]2Юрий Зотов © (28.04.04 23:15) [9]
>> старый добрый Паскаль пока еще никто не отменял
Звучит как "стакан старого доброго молока".
← →
TButton © (2004-04-29 04:27) [12]>Звучит как "стакан старого доброго молока".
знаете... я как-то хлебнул старого молока из пакета... после этого случая я осознал, что "не все старое - доброе"
← →
Fay © (2004-04-29 04:53) [13]Я о том же ....
← →
TUser © (2004-04-29 07:36) [14]Вот у меня есть такой модуль. Функция GetDouble взвратит число независимо от DecimalSeparator. Остальное тоже может пригодиться.
unit uNumChecker;
interface
uses
SysUtils, Strutils, math;
type
EWrongRule = class(Exception)
public
constructor Create(Rule:string);
end;
function IsValueRight(Rule:string; Value:double):boolean;
procedure MyVal(Value:string; var V:integer; var Code:integer);
function GetDouble(Value:string; var Code:integer):double;
implementation
procedure MyVal(Value:string; var V:integer; var Code:integer);
var i:integer; f:boolean;
begin
i:=1; f:=true;
while f and (i<=length(Value)) do
if Value[i]="0" then inc (i)
else f:=false;
if f then begin Code:=0; V:=0; end else
val(copy(Value,i,length(Value)-i+1),V,Code);
end;
function GetDouble(Value:string; var Code:integer):double;
var i,j,k,c:integer;
begin
Code:=0;
k:=pos(".",Value);
if k=0 then Val(Value,result,Code) else begin
if posex(".",Value,k+1)<>0 then
raise EWrongRule.Create("Wrong double value: """+Value+"""");
MyVal(copy(Value,1,k-1),i,c);
if c<>0 then raise EWrongRule.Create("Wrong double value: """+Value+"""");
Val(copy(Value,k+1,length(Value)-k),j,c);
if c<>0 then raise EWrongRule.Create("Wrong double value: """+Value+"""");
c:=length(Value); // while Value[c]="0" do dec(c);
k:=c-k;
if j = 0 then result:=i else
result:=i+j/power(10,k);
end;
end;
function IsValueRight(Rule:string; Value:double):boolean;
var s:string; i,j:integer;
function IsIn(SubRule:string; Value:double):boolean;
var i:integer; d:double;
begin
result:=false;
i:=pos("-",SubRule);
if i = 0 then begin
Val(SubRule,d,i);
if (i=0) and (abs(d-Value)<0.01) then
result:=true
else result:=false;
end else if posex("-",SubRule,i+1)<>0 then
raise EWrongRule.Create("Wrong SubRule: """+SubRule+"""")
else if i=1 then begin
val(copy(SubRule,2,length(SubRule)-1),d,i);
if (i=0) and (d>=Value) then
result:=true
else result:=false;
end else if i=length(SubRule) then begin
val(copy(SubRule,1,length(SubRule)-1),d,i);
if (i=0) and (d<=Value) then
result:=true
else result:=false;
end else begin
d:=GetDouble(copy(SubRule,1,i-1),j);
if (j=0) and (d<=Value) then begin
d:=GetDouble(copy(SubRule,i+1,length(SubRule)-i),j);
if (j=0) and (d>=Value) then
result:=true
else result:=false;
end else result:=false;
end;
end;
begin
s:="";
for i:=1 to length(Rule) do
if Rule[i] in ["0".."9",",","-","."] then s:=s+Rule[i]
else if Rule[i]<>" " then
raise EWrongRule.Create(Rule);
result:=false;
i:=pos(",",s); j:=1;
if i=0 then i:=length(s)+1;
repeat begin
result:=result or IsIn(copy(s,j,i-j),Value);
j:=i+1; i:=posex(",",s,j);
end
until (i=0) or result;
result:=result or IsIn(copy(s,j,length(s)-j+1),Value);
end;
constructor EWrongRule.Create(Rule:string);
begin
inherited Create("Wrond Rule: """+Rule+"""");
end;
end.
← →
Piople © (2004-04-29 07:40) [15]Блин а мож просто взять pos??? И после каждого нахождения пробуде копировать слова в массив???
← →
Anatoly Podgoretsky © (2004-04-29 07:41) [16]Германн © (29.04.04 03:09) [10]
Это если количество фиксированое, а при переменном придется делать в цикле
for i := 0 to n-1 do
read(F, ar[j,i]);
readLn(f);
← →
Юрий Зотов © (2004-04-29 08:40) [17]> Fay © (29.04.04 04:02) [11]
> TButton © (29.04.04 04:27) [12]
> Fay © (29.04.04 04:53) [13]
Возражение по существу, что и говорить.
← →
Vit@ly © (2004-04-29 10:06) [18]Поддерживаю Anatoly Podgoretsky © (29.04.04 07:41) [16]
Хотя мне показалось, что я это уложил в посте [4] в строке
//здесь разберись со строками и столбцами, никакого парсинга не потребуется
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.037 c