Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.07.04;
Скачать: [xml.tar.bz2];

Вниз

Поиогите разобраться   Найти похожие ветки 

 
Igit   (2002-06-21 21:10) [0]

Поиогите разобраться

procedure setignor;
var ignored_ini:TextFile;
IgnorSoft: array of PChar;
z:integer; //количество путей
begin
// Finalize(ignored_ini);
AssignFile(ignored_ini, "ignored.ini");
reset(ignored_ini);
SetLength(IgnorSoft,z); //длина масива равна количеству путей
z:=0;
while SeekEof(ignored_ini)=false do //остальное до конца файла это пути
begin
Readln(ignored_ini, IgnorSoft[z]); //вот здесь ошибка "illegal type in Read/Readln statement"
z:=z+1;
end;
CloseFile(ignored_ini);
end;

Нужно заполнить массив длиной z (1-ая строка ignored.ini) путями - остальные строки.
Если IgnorSoft: array of String; , то всё работает, но мне нужно IgnorSoft: array of PChar;

Или подскажите как переделать String в PChar.


 
jedi   (2002-06-21 21:18) [1]

uses SysUtils;
var

A: array[0..79] of Char;
S: String;
begin
S := "Honk if you know Blaise.";
StrPCopy(A, S);
end;

ili prostoe privedenie tipov


 
aus   (2002-06-21 22:04) [2]

первое что в голову пришло...
Если тебе именно в Array of PChar нужно считать, попробуй читать сначала в string, а потом преобразовывать в pchar.
var s: string;
..........
readln(ignored_ini,s);
ignorSoft[z] := pchar(s);
.............



 
Anatoly Podgoretsky   (2002-06-21 22:52) [3]

А память Пушкин будет выделять?


 
Igit   (2002-06-22 09:36) [4]

Память?


 
Anatoly Podgoretsky   (2002-06-22 09:52) [5]

IgnorSoft: array of PChar;
IgnorSoft[z]);


 
Igit   (2002-06-22 12:31) [6]

Ок, я сделал так:

var: IgnorSoft_PCar: array of PChar;
const z = 3;
begin
SetLength(IgnorSoft_PCar, z);
открываю ignored_ini для чтения
............................
z:=0;
while SeekEof(ignored_ini)=false do //пока файл не кончился
begin
Readln(ignored_ini, s);
IgnorSoft_PCar[z]:=PChar(s);
z:=z+1;
end;
end.
............................
После первого выполнения цыкла:
s="NetCaptor"
z=0
IgnorSoft_PCar("NetCaptor", nil, nil)
После второго выполнения цыкла:
s="Elma"
z=1
IgnorSoft_PCar("Elma", "Elma", nil)
После третьего выполнения цыкла:
s="Delphi 5"
z=2
IgnorSoft_PCar("Delphi 5", "Delphi 5", "Delphi 5").
Но мне нужно после третьего чтобы было так:
IgnorSoft_PCar("NetCaptor", "Elma", "Delphi 5")

Я никак не могу понять, что я делаю не так.


 
Юрий Зотов   (2002-06-22 13:06) [7]

Сохранять PChar"ы в файле? Бессмыслица. В следующем сеансе все эти PChar"ы окажутся недействительными. Сохранять надо строки, их же и читать, а в PChar преобразовывать уже готовую строку.

И зачем делать это в стиле старого доброго Паскаля, если Вы работаете в Delphi, где есть готовый TStringList с его SaveToFile и LoadFromFile? А также TIniFile с его готовой поддержкой секционирования и методами чтения/записи.

Ошибка же у Вас в том, что смысла PChar Вы, извините, не понимаете. PChar - это указатель на строку, адрес ее тела (то есть, первого символа), вот и все.

Вы читаете строку S и адрес ее первого символа заносите в первый элемент массива. Все ОК. Далее Вы снова читаете строку S и адрес ее первого символа заносите во второй элемент массива. НО ЧТО ИМЕННО ЗАПИСАЛОСЬ ВО ВТОРОЙ ЭЛЕМЕНТ? ТОТ ЖЕ САМЫЙ АДРЕС, ЧТО И В ПЕРВЫЙ. А ЧТО ПОЛУЧИЛОСЬ В ПЕРВОМ ЭЛЕМЕНТЕ? В НЕМ ОСТАЛСЯ ТОТ ЖЕ АДРЕС, ЧТО И БЫЛ, И ОН ПО-ПРЕЖНЕМУ УКАЗЫВАЕТ НА ПЕРВЫЙ СИМВОЛ СТРОКИ - НО СТРОКА-ТО УЖЕ ДРУГАЯ!!!!

Поэтому, сколько бы раз Вы не прогоняли цикл, ВСЕ ЭЛЕМЕНТЫ МАССИВА БУДУТ ВСЕГДА СОДЕРЖАТЬ ОДНО И ТО ЖЕ - АДРЕС ПЕРВОГО ЭЛЕМЕНТА СТРОКИ. А ТЕЛО СТРОКИ ВСЕГДА БУДЕТ РАВНО ПОСЛЕДНЕМУ СЧИТАННОМУ ИЗ ФАЙЛА. И ПОЭТОМУ ВСЕ PChar"ы В МАССИВЕ ВСЕГДА БУДУТ ДАВАТЬ ОДНО И ТО ЖЕ.

В чем Вы уже и убедились.

Поэтому, либо выделяйте память под КАЖДУЮ строку ручками (а потом не забудьте ее освободить), либо просто используйте TStringList и не мучайтесь.


 
Igit   (2002-06-22 14:36) [8]

>2 Юрий Злотов
Большое спасибо, что разъясноли мне всё, вы правы - я НЕПРАВИЛЬНО понимал (подразумевал) слово "PChar". Но теперь, когда всё понял, я не могу понять как осуществить свою идею.
А идея у меня вот какая:
У меня есть файл "ignored.ini". В нем записаны текстовый заголовки окон программ. Я порверяю есть ли хотябы одно окно с таким заголовком и если есть значит моя программа остонавливается на например 500мс. и проверяет снова. Если окон с таким заголовком нет, то программа делает свои дела. Я это делаю так:

function prover_ignor : bool;
var n:integer;
begin
prover_ignor:=false;
n:=0;
while n<z do
if findwindow(nil, IgnorSoft_PCar[n])<>0 then
begin
prover_ignor:=true;
break;
end
else
n:=n+1;

end;


А вот чтобы заполнить массив вы уже видели как я хотел сделать.

Выходит я понял вас так : "Какой длины массив IgnorSoft_PCar: array of PChar столько строк должно и быть, то есть я должен создавать строки динамически". Но я НЕ ЗНАЮ, и НИ МОГУ ДАЖЕ ПРЕДПОЛОЖИТЬ КАК ЭТО ОСУЩЕСТВИТЬ.
Программа вся написана на API. Извините за занудность, я только учусь.
С Уважением IGIT


 
Igit   (2002-06-22 14:38) [9]

там (выше) в первом предложении опечатка :)


 
Юрий Зотов   (2002-06-22 16:20) [10]

1. Вот далеко не самый лучший, но зато самый простой вариант.


uses
..., Classes;

function WindowExists: boolean;
var
i: integer;
begin
Result := False;
with TStringList.Create do
try
LoadFromFile("Ignored.ini");
for i := 0 to Count - 1 do
if FindWindow(nil, PChar(Strings[i])) <> 0 then
begin
Result := True;
Break
end
finally
Free
end
end;


2. Вот вариант посложнее, но зато соответствующий Вашему желанию не использовать объекты VCL, а использовать только чистый Паскаль и API. Будет работать в Delphi 4 и старше (использован динамический массив, которые появились в Delphi 4).


var
Captions: array of PChar;

procedure ReadCaptions; // Вызвать в начале программы
var
F: TextFile;
S: string;
begin
AssignFile(F, "Ignored.ini");
Reset(F);
while not EoF(F) do
begin
ReadLn(F, S);
if S <> "" then
begin
// Добавляем к массиву новый элемент
SetLength(Captions, Length(Captions + 1));
// Выделяем память под тело будущей строки
// и полученный адрес заносим в этот новый элемент
GetMem(Captions[High(Captions)], Length(S) + 1);
// Копируем в эту память тело прочитанной из файла
// строки вместе с завершающим нулем
CopyMemory(Captions[High(Captions)], @S[1], Length(S) + 1)
end
end;
CloseFile(F)
end;

function WindowExists: boolean;
var
i: integer;
begin
Result := False;
for i := Low(Captions) to High(Captions) do
if FindWindow(nil, Captions[i]) <> 0 then
begin
Result := True;
Break
end
end;

procedure ClearCaptions; // Вызвать в конце программы.
vаr
i: integer;
begin
// Освобождаем память, занимаемую телами строк. Нисходящий
// цикл не обязателен, но для менеджера памяти так лучше.
for i := High(Captions) downto Low(Captions) do
FreeMemory(Captions[i], Length(String(Captions[i])) + 1);
// Освобождаем память, занимаемую самим массивом
Captions := nil
end;



 
Юрий Зотов   (2002-06-22 16:53) [11]

Тоже опечатка.
:о)

Конечно, в процедуре ReadCaptions должно быть не
SetLength(Captions, Length(Captions + 1));
а
SetLength(Captions, Length(Captions) + 1);

Вообще, советую рассматривать этот код не как абсолютный, а как пример работы с динамическими массивами, указателями, динамической памятью, PChar и String. Поняв его, Вы всегда напишете нужный код сами, для любого конкретного случая.


 
Igit   (2002-06-22 21:47) [12]

>2 Юрий Зотов
Спасибо большое, работает. Разобраться попробовал, но не всё понял, наверно потому что вечер и уставший, попробую завтра, если что-то не будет доходить (такой уж я :( , то спрошу:))


 
Igit   (2002-06-22 23:33) [13]

>2 Юрий Зотов
Спустя два часа...
Igit (довольный): Я понял!!!
..................................
Что то мне вдруг в голову залетело после мучительного раздумья и я сделал так:

var captions:array of string;
z: integer;
procedure ReadCaptions; // Вызвать в начале программы
var
F: TextFile;
begin
AssignFile(F, "Ignored.ini");
Reset(F);
readln(f, z);
SetLength(Captions, z);
while not EoF(F) do
z:=0;
begin
ReadLn(F, Captions[z]);
z:=z+1;
end;
CloseFile(F)
end;

function WindowExists: boolean;
var
i: integer;
begin
Result := False;
i:=0;
while i<z do
if FindWindow(nil, PChar[Captions[i]) <> 0 then
begin
Result := True;
Break
end else n:=n+1;

end;


Ну как?


 
Юрий Зотов   (2002-06-23 06:54) [14]

Нормально. Это самое "паскалевское" решение - использовать массив не просто указателей, а строк и тем самым почти всю работу по распределению памяти возложить на компилятор.

Но есть одно "но" - слишком легко ломается.

Беру файл Ignored.ini, редактирую его вручную, в первую строку записываю, например, -7, сохраняю. Все, программа работать не будет: SetLength(Captions, -7) не пройдет.

Если это не критично, можно оставить и так. Только если уж число строк в файле теперь стало заранее известно, то оба цикла while стоит заменить на for - они гораздо быстрее работают. И где-то в конце желательно очистить массив (хотя при завершении программы система все равно освободит всю память, которую она использовала, но все же это хороший стиль).



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.07.04;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.009 c
6-9941
Sound
2002-04-22 23:03
2002.07.04
Отправка HTTP запроса


14-9984
Arhangel
2002-06-01 21:29
2002.07.04
Подскажите самый простой компонент


6-9951
Donal_Graeme
2002-04-24 18:47
2002.07.04
HTTP-прокси - получение данных


14-9961
ev
2002-06-01 14:49
2002.07.04
oberon


1-9783
I am
2002-06-23 19:02
2002.07.04
Как создать свои кнопки на заголовке формы?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский