Вопросы по программированию

Автор Богдан, 03 Листопад 2007, 11:41:18

Попередня тема - Наступна тема

βεερ_βooρ

Цитата: Fersifex від 22 Лютий 2008, 18:30:59
Скажите, плиз, почему у меня при
gcc file_name.cpp
выдается длинный перечень "чего-то там"?
Например обычный "Hello world" почти втупую списанный с учебника:
GCC = GNU C Compiler
Вызывай  g++ (т.к. программа у тебя написана на С++), иначе у тебя будут маленькие проблемы  :)
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Fersifex

Цитата: beep_boop від 22 Лютий 2008, 18:42:41
GCC = GNU C Compiler
Вызывай  g++ (т.к. программа у тебя написана на С++), иначе у тебя будут маленькие проблемы  :)
А я думал, что для C - команда "сс". Спасибо :)
Книга - это зеркало, и если в него смотрится обезьяна, то оттуда не может выглянуть лик апостола

Bismark

У мене є таке от питання...

Як у Делфі можна зкопіювати файл? Наче є така WinAPI функція CopyFile, але я не знайшов інформації як її можна застосувати на Делфі...

Конкретніше мене цікавить, чи є можливість зкопіювати сам ехе-файл цієї програми? Тобто, чи може програма (один ехе-файл) сама себе зкопіювати у потрібну папку?

βεερ_βooρ

Цитата: Fersifex від 22 Лютий 2008, 18:47:40
А я думал, что для C - команда "сс". Спасибо :)
master@shiray:~$ ls -l `which cc`
lrwxrwxrwx 1 root root 3 2008-02-16 10:53 /usr/bin/cc -> gcc*

master@shiray:~$ ls -l `which c++`
lrwxrwxrwx 1 root root 3 2008-02-16 10:53 /usr/bin/c++ -> g++*



Цитата: Bismark від 22 Лютий 2008, 22:29:32
У мене є таке от питання...

Як у Делфі можна зкопіювати файл? Наче є така WinAPI функція CopyFile, але я не знайшов інформації як її можна застосувати на Делфі...

Конкретніше мене цікавить, чи є можливість зкопіювати сам ехе-файл цієї програми? Тобто, чи може програма (один ехе-файл) сама себе зкопіювати у потрібну папку?
http://msdn2.microsoft.com/en-us/library/aa363851(VS.85).aspx
BOOL WINAPI CopyFile(
  __in  LPCTSTR lpExistingFileName,
  __in  LPCTSTR lpNewFileName,
  __in  BOOL bFailIfExists
);

А в чем собственно затруднение? Ф-ция есть, названия параметров говорят сами за себя...
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Bismark

Цитата: beep_boop від 22 Лютий 2008, 23:42:32
http://msdn2.microsoft.com/en-us/library/aa363851(VS.85).aspx
BOOL WINAPI CopyFile(
  __in  LPCTSTR lpExistingFileName,
  __in  LPCTSTR lpNewFileName,
  __in  BOOL bFailIfExists
);

А в чем собственно затруднение? Ф-ция есть, названия параметров говорят сами за себя...
Я так розумію, перший та другий параметри - не просто назва файлу, а назва з повним шляхом до нього?
Я не знаю мови С, тому не розумію, що це за тип такий LPCTSTR...

А складність полягає у тому, що мене не влаштовує залежність функції від назви файлу. Це звичайно логічна залежність, але я хочу копіювати не якийсь інший файл, а щоб програма могла зкопіювати сама себе у потрібний каталог.
Тому мені бажано, щоб таке копіювання проходило без урахування назви файлу (на той випадок, якщо файл виявиться перейменованим).

βεερ_βooρ

Цитата: Bismark від 24 Лютий 2008, 20:36:27
Я не знаю мови С, тому не розумію, що це за тип такий LPCTSTR...
Паскаль соответствие - PChar.

Цитата: Bismark від 24 Лютий 2008, 20:36:27
А складність полягає у тому, що мене не влаштовує залежність функції від назви файлу. Це звичайно логічна залежність, але я хочу копіювати не якийсь інший файл, а щоб програма могла зкопіювати сама себе у потрібний каталог.
Тому мені бажано, щоб таке копіювання проходило без урахування назви файлу (на той випадок, якщо файл виявиться перейменованим).
В чем проблеммы? 0 параметр коммандной строки - вызываймое имя файла и он присутствует всегда.
Воспользуйся ф-цией ParamStr:
http://www.delphibasics.co.uk/RTL.asp?Name=ParamStr

Тебе нужно что-то вроде:
CopyFile(pchar(ParamStr(0)), pchar(<куда копировать>), <Не переписывать ли>);
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Bismark

#106
Цитата: beep_boop від 24 Лютий 2008, 20:44:50
Паскаль соответствие - PChar.
В чем проблеммы? 0 параметр коммандной строки - вызываймое имя файла и он присутствует всегда.
Воспользуйся ф-цией ParamStr:
http://www.delphibasics.co.uk/RTL.asp?Name=ParamStr

Тебе нужно что-то вроде:
CopyFile(pchar(ParamStr(0)), pchar(<куда копировать>), <Не переписывать ли>);
Дуже дякую - це саме те, що мені було потрібно!
Тримай плюс ;)

UPDATE:
Зявилась певна проблема з цим кодом:
CopyFile(pchar(ParamStr(0)), pchar(<куда копировать>), <Не переписывать ли>);
Справа в тому, що функція ParamStr(0) повертає значення типу PAnsiChar, і якщо у другому параметрі функції я вказую шлях типу string, при компіляції виводиться помилка, що типи PAnsiChar та String несумісні :(

Крім того перед копіюванням я хочу перевірити існування файлу на місці, куди я хочу його зкопіювати (щоб копіювання відбулося лише при першому запуску програми).
Я пишу:

var Path: string //шлях до місця призначення файлу
***
if not ParamStr(0) = Path then ...

або
if not Application.ExeName = Path then ...
Компілятор знову видає помилку про несумісність типів PAnsiChar та String :(

Ось я і не можу зрозуміти - чому є така несумісніть?
Адже якщо написати такий код:

Label1.Caption := ParamStr(0);

То програма прекрасно компілюється, хоча властивість Caption повинна бути типу String.

βεερ_βooρ

Цитата: Bismark від 24 Лютий 2008, 21:14:43
Справа в тому, що функція ParamStr(0) повертає значення типу PAnsiChar, і якщо у другому параметрі функції я вказую шлях типу string, при компіляції виводиться помилка, що типи PAnsiChar та String несумісні :(
Так вот сразу сказать не могу - я Дельфи не запускал уже года 4.
Тем более, что тут работало:
http://freepascal.ru/forum/viewtopic.php?t=2993
Цитата: Bismark від 24 Лютий 2008, 21:14:43
Крім того перед копіюванням я хочу перевірити існування файлу на місці, куди я хочу його зкопіювати (щоб копіювання відбулося лише при першому запуску програми).
Если 3 параметр ф-ции равен true - перезаписи существующего файла не будет. Зачем платить больше? :)
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Bismark

Цитата: beep_boop від 26 Лютий 2008, 01:19:27
Так вот сразу сказать не могу - я Дельфи не запускал уже года 4.
Тем более, что тут работало:
http://freepascal.ru/forum/viewtopic.php?t=2993
Все, питання вже вирішено :)
Справа в тому, що в своєму коді я сам допустив помилку
var Path: string //шлях до місця призначення файлу
***
if not ParamStr(0) = Path then ...

Я забув, що найвищий приорітет має операція логічного НІ, і тому у блоці if ... then компілятор намагався спочатку інвертувати (для порівняння) змінну типу PChar, що й викликало проблеми.
Достатньо було поставити дужки у блоці порівняння змінних, і помилка зникла :)
Цитата: beep_boop від 26 Лютий 2008, 01:19:27
Если 3 параметр ф-ции равен true - перезаписи существующего файла не будет. Зачем платить больше? :)
Перезапису не буде, але я хотів щоб програма навіт ьне намагалася копіюватися, у разі існування своєї копії у потрібному місці.
Результуючий код вийшов таким:
  if not (PChar(Application.ExeName) = PChar(Path)) then begin
    if not FileExists(Path) then begin
      CopyFile(PChar(ParamStr(0)), PChar(Path), False);
    end;
  end;

Насправді метод Application.ExeName та функція ParamStr(0) повертають абсолютно однакові результати. Навіть сам не знаю навіщо я використав обидва варіанти одночасно :)

βεερ_βooρ

Цитата: Bismark від 26 Лютий 2008, 23:40:33
  if not (PChar(Application.ExeName) = PChar(Path)) then begin
    if not FileExists(Path) then begin
      CopyFile(PChar(ParamStr(0)), PChar(Path), False);
    end;
  end;

CopyFile(PChar(ParamStr(0)), PChar(Path), True);
Это будет тоже самое, просто тогда вместо тебя проверку проведет ф-ция CopyFile
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Bismark

Цитата: beep_boop від 26 Лютий 2008, 23:53:53
CopyFile(PChar(ParamStr(0)), PChar(Path), True);
Это будет тоже самое, просто тогда вместо тебя проверку проведет ф-ция CopyFile
А як щодо цього:
ЦитатаbFailIfExists

If this parameter is TRUE and the new file specified by lpNewFileName already exists, the function fails. If this parameter is FALSE and the new file already exists, the function overwrites the existing file and succeeds.
Я так розумію, що при значенні параметра TRUE, при спробі замінити існуючий файл буде викликана помилка.
Щоб уникниту цієї помилки, я примусово і роблю цю перевірку.

βεερ_βooρ

Цитата: Bismark від 27 Лютий 2008, 00:59:20
А як щодо цього:Я так розумію, що при значенні параметра TRUE, при спробі замінити існуючий файл буде викликана помилка.
Щоб уникниту цієї помилки, я примусово і роблю цю перевірку.
Читаем дальше:
ЦитатаReturn Value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Bismark

Цитата: beep_boop від 27 Лютий 2008, 01:08:07
Читаем дальше:
В Паскалі немає таких команд, як наприклад "Return 0;" у С++.
Тому я не знаю що там може повернути функція. Мені необхідно лише щоб вона була у будь-якому випадку виконана успішно.
От що наприклад станеться з програмою, якщо "function returns zero"? Я не знаю що це означає...

βεερ_βooρ

Цитата: Bismark від 27 Лютий 2008, 01:35:05
В Паскалі немає таких команд, як наприклад "Return 0;" у С++.
Вообще-то return 0; (C различает регистр)  ;)
В Паскале вместо этого присаивают значение имени ф-ции или Result
Цитата: Bismark від 27 Лютий 2008, 01:35:05
От що наприклад станеться з програмою, якщо "function returns zero"? Я не знаю що це означає...
Это значит, что она вернет 0 :)
Т.е. false
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Edd.Dragon

#114
Цитата: Bismark від 24 Лютий 2008, 20:36:27
Я так розумію, перший та другий параметри - не просто назва файлу, а назва з повним шляхом до нього?
Я не знаю мови С, тому не розумію, що це за тип такий LPCTSTR...
Ну тип параметра логично предположить - строка. Для того, чтобы убедиться - достаточно полазить по исходникам RTL и почитать помощь.

все функции WinAPI в дельфи собраны в Windows.pas. Т.е. его нужно подключить в коде. Далее
1. Набираем FileCopy и жмем на нем F1 - читаем внимально помощь по параметрам и использованию, если есть смотрим пример.
2. Если что-то осталось не понятно, то нужно заглянуть в соответсвующий исходник, он указан в помощи по функции (в нашем случае Windows.pas). Исходники должны быть установлены вместе с Дельфи. Лазить вручную - неблагодарное занятие. Поэтому скачиваем GExperts и устанавливаем. После этого, Ctrl+Click на именах функций будет открывать нужный файл в нужном месте.

Т.е. кликаем по FileCopy (при этом слово подсвечивается как линк) и если ты не забыл выше написать uses Windows, то тебя перекинет в Windows.pas к объявлению этой функции. Далее тебе непонятен тип параметра - снова кликаешь по его имени (или названию типа - не помню) и попадаешь на его объявление. В итоге ты допрыгаешься до строчки типа

type
  LPCTSTR = string;

и все станет ясно :)

Кроме того, GExperts предоставляют кучу дргих возможностей. Которые собраны в в целое длинное меню! На любые действия можно повесить хоткей.

В общем исходники VCL\RTL + справка Delphi + GExperts = идеальный учитель ;)

Цитата
if not (PChar(Application.ExeName) = PChar(Path)) then begin
    if not FileExists(Path) then begin
      CopyFile(PChar(ParamStr(0)), PChar(Path), False);
    end;
  end;

А зачем при сравнении string со string ты из преобразуешь к PChar и пвместо "не равно" используешь "не (равно)", к тому же разбил на два условия?

Так будет оптимальнее:


if (Application.ExeName != Path) and not FileExists(Path) then
begin
    CopyFile(PChar(Application.ExeName), PChar(Path), False);
end;


или так:


if not ((Application.ExeName = Path) or FileExists(Path)) then
begin
    CopyFile(PChar(Application.ExeName), PChar(Path), False);
end;


Bismark

Цитата: edd_k від 27 Лютий 2008, 11:32:49
все функции WinAPI в дельфи собраны в Windows.pas. Т.е. его нужно подключить в коде. Далее
1. Набираем FileCopy и жмем на нем F1 - читаем внимально помощь по параметрам и использованию, если есть смотрим пример.
2. Если что-то осталось не понятно, то нужно заглянуть в соответсвующий исходник, он указан в помощи по функции (в нашем случае Windows.pas). Исходники должны быть установлены вместе с Дельфи. Лазить вручную - неблагодарное занятие. Поэтому скачиваем GExperts и устанавливаем. После этого, Ctrl+Click на именах функций будет открывать нужный файл в нужном месте.

Т.е. кликаем по FileCopy (при этом слово подсвечивается как линк) и если ты не забыл выше написать uses Windows, то тебя перекинет в Windows.pas к объявлению этой функции. Далее тебе непонятен тип параметра - снова кликаешь по его имени (или названию типа - не помню) и попадаешь на его объявление. В итоге ты допрыгаешься до строчки типа

type
  LPCTSTR = string;

и все станет ясно :)

Кроме того, GExperts предоставляют кучу дргих возможностей. Которые собраны в в целое длинное меню! На любые действия можно повесить хоткей.

В общем исходники VCL\RTL + справка Delphi + GExperts = идеальный учитель ;)
Мені не довелося встановлювати ніякого GExperts - сам Делфі має вбудовану функцію, що при Ctrl+Click відкривається підключена бібліотека і вказує на потрібну функцію :)
Цитата: edd_k від 27 Лютий 2008, 11:32:49
А зачем при сравнении string со string ты из преобразуешь к PChar
Проблема в тому, що змінна Application.ExeName насправді не типу String, а pAnsiChar, і при прямому порівнянні таких типів компілятор виводить помилку про невідповідність типів.
Чесно кажучи, я не зовсім розумію, що це за типи такі pChar та pAnsiChar, але функцію перетворення я знайшов у хелпі до Делфі, де якраз і описувалося порівняння різних типів даних.
Цитата: edd_k від 27 Лютий 2008, 11:32:49
А зачем при сравнении вместо "не равно" используешь "не (равно)", к тому же разбил на два условия?
Я використовую дві умови, тому що спочатку я хочу просто перевірити звідки був запущений файл. Якщо шлях до запущеного файлу правильний, то умова не буде виконана, і всі блоки всередені будуть проігноровані.
Якщо ж файл запущений з будь-якого іншого місця, то перевіряється існування копії файлу у потрібному місці. Знову ж таки, якщо в тому місці файл вже існує, то блок завершується, а якщо не існує, то вже тоді відбувається копіювання.

Toxic_V

#116
Нубське питання: якою командою можна видаляти папки через bat файл?

Anton T.

Цитата: Toxic_V від 27 Лютий 2008, 21:40:30
Нубське питання: якою командою можна видаляти папки через bat файл?
Команда RD - удаление каталога.
Цитата
RMDIR [/S] [/Q] [диск:]путь
RD [/S] [/Q] [диск:]путь

    /S      Удаление дерева каталогов, т. е. не только указанного каталога,
            но и всех содержащихся в нем файлов и подкаталогов.

    /Q      Отключение запроса подтверждения при удалении дерева каталогов
            с помощью ключа /S.

Edd.Dragon

#118
Цитата: Bismark від 27 Лютий 2008, 21:12:18
Мені не довелося встановлювати ніякого GExperts - сам Делфі має вбудовану функцію, що при Ctrl+Click відкривається підключена бібліотека і вказує на потрібну функцію :)

Проблема в тому, що змінна Application.ExeName насправді не типу String, а pAnsiChar
М-да, совсем уже Дельфю забыл...

Цитата: Bismark від 27 Лютий 2008, 21:12:18
не типу String, а pAnsiChar, і при прямому порівнянні таких типів компілятор виводить помилку про невідповідність типів.
Чесно кажучи, я не зовсім розумію, що це за типи такі pChar та pAnsiChar, але функцію перетворення я знайшов у хелпі до Делфі, де якраз і описувалося порівняння різних типів даних.
PChar и PAnsiChar - это указатель на символ. Тогда правильно использовать соответсвующую функцию сравнения
AnsiCompareText или AnsiCompareStr. Одна из них по ходу игнорирует регистр ;)

Цитата: Bismark від 27 Лютий 2008, 21:12:18
Я використовую дві умови, тому що спочатку я хочу просто перевірити звідки був запущений файл. Якщо шлях до запущеного файлу правильний, то умова не буде виконана, і всі блоки всередені будуть проігноровані.
Кста, если тебе необходимо сравнивать только пути, а не полное имя файла, то тогда сначала вычлени его ExtractFilePath(Application.ExeName) или ExtractFileDir. Отличаются наличием\отсутсвием слеша в конце пути.

Toxic_V

2AntonT Спасибі
Але яка різниця між RD i RMDIR? Чи вони однакові?

Anton T.

#120
Цитата: Toxic_V від 29 Лютий 2008, 13:44:16
2AntonT Спасибі
Але яка різниця між RD i RMDIR? Чи вони однакові?
Да почти одинаковая. Смотри
http://win-faq.ru/txpwinfaq/article/konsolnye-komandy-windows-komanda-rmdir
http://webdocs.ru/content-508.html

Bismark

Цитата: edd_k від 29 Лютий 2008, 10:53:30
AnsiCompareText или AnsiCompareStr. Одна из них по ходу игнорирует регистр ;)
А звичайним порівнянням воно неправильно працюватиме? Мені потрібно просто порівняти текст, і лише наявність строки типу pAnsiChar вимагає використання функції PChar.
Цитата: edd_k від 29 Лютий 2008, 10:53:30
Кста, если тебе необходимо сравнивать только пути, а не полное имя файла, то тогда сначала вычлени его ExtractFilePath(Application.ExeName) или ExtractFileDir. Отличаются наличием\отсутсвием слеша в конце пути.
Ні, мені необхідно перевіряти ім'я файла також.
Але все одно дякую за пораду - можливо колись мені знадобляться такі функції :)

Edd.Dragon

#122
Так, добрался домой до Дельфи. Application.ExeName имеет тип string! Так что, компилятор у тебя не на него ругался :-X А я уж подумал, что совсем все забыл %)


Цитата: Bismark від 29 Лютий 2008, 20:08:31
і лише наявність строки типу pAnsiChar вимагає використання функції PChar.
Это не функция, а указание компилятору использовать величину одного типа как величину другого. Многое компилятор и сам "преобразует", но где ему что-то неочевидно, он просит тебя указать явно. В данном случае ты стандартную дельфийную строку (string) приводишь к указателю на ее начало, стандартный строковый тип виндовых функций (PChar), т.е. к "Pointer на Char". В винде просто раньше было принято строку задавать как указатель на первый ее символ, а в конце строки должен быть символ с кодом 0. В результате ты понятия не имеешь какой длины строка, пока ее не просмотришь целиком - это жутко неудобно. В ОО-языках используется человеческое представление строк, т.е. по сути массив символов (сначала длина, потом символы). Дельфи и C++ к тому же автоматически в конец строки добавляют символ \0, что бы ты об этом не заботился, используя их в виндовых функциях.

Так вот, PChar(s) - это адрес первого символа твоей строки и (PChar(s1) = PChar(s2)) - это сравнение указателей. Т.е. ты проверяешь, ссылаются ли твои строки на одно и то же место или нет. Запусти этот код (я использую AnsiString и PAnsiChar, в Delphi7 это тоже самое что и string, PChar, но с более полным названием):


program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  s1, s2, s3: AnsiString;

begin
  s1 := 'it is string';
  s2 := 'it is string';
  s3 := s1;

  if(PAnsiChar(s1) = PAnsiChar(s2)) then
  begin
    WriteLn('s1 = s2');
  end;

  if(PAnsiChar(s1) = PAnsiChar(s3)) then
  begin
    WriteLn('s1 = s3');
  end;

  ReadLn;
end.


"Одинаковыми" окажутся только s3 и s1, т.к. на самом деле, пока ты одну из них не изменишь - это одна и та же строка, находящаяся в памяти в одном экземпляре, а вот s1 "не равно" s2 - это две разные строки, в разных местах.

А вот содержимое этих всех строк одинаково ;) s1 = s2, где s1, s2: string - это сравнение именно содержимого. А чтобы сравнить содержимое по указателям PAnsiChar, можно использовать специальные виндовые функции (НЕ те, которые я привел в предыдущем посте - там я по памяти првел функции сравнения для обычных строк, а не для указателей). А можно без использования каких либо функций просто привести PAnsiChar к AnsiString и уже обычным сравнением сравнить "нормальные" строки, т.е. сделать обратное тому, что сделал ты. Вот в этом коде оба условия выполнятся:


program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  s1, s2, s3: AnsiString;

begin
  s1 := 'it is string';
  s2 := 'it is string';
  s3 := s1;

  if(s1 = s2) then
  begin
    WriteLn('s1 = s2');
  end;

  if(s1 = s3) then
  begin
    WriteLn('s1 = s3');
  end;

  ReadLn;
end.



В твоем же случае надо выяснить, в чем была проблема. Но если твоя переменная Path тоже имеет тип string, то следующий код должен успешно работать. А залезание в дебри указателей хоть и оказалось ненужным, зато показало тебе разницу между сравнением строк и указателей на них.


// если Path имеет тип AnsiString или string, то никаких ошибок быть не должно
if (Application.ExeName <> Path) then
begin

end;


При сравнении путей не лишним было бы, что бы "С:\Windows" равнялась "c:\windows"? Тогда так:


if AnsiCompareText(Application.ExeName, Path) <> 0 then
begin

end;


βεερ_βooρ

Цитата: edd_k від 29 Лютий 2008, 23:41:28
В винде просто раньше было принято строку задавать как указатель на первый ее символ,
А сейчас что-то изменилось?
Цитата: edd_k від 29 Лютий 2008, 23:41:28
а в конце строки должен быть символ с кодом 0. В результате ты понятия не имеешь какой длины строка, пока ее не просмотришь целиком - это жутко неудобно.  В ОО-языках используется человеческое представление строк, т.е. по сути массив символов (сначала длина, потом символы).
Не согласен.
У реализации паскалевкого подхода к строкам есть существенные недостатки при сомнительных преимуществах.
Затратность вычисления длины строки в С - довольно спорный вопрос.
  - Длину строки далеко не всегда необходимо знать
  - С другой стороны паскалевский подход позволяет несколько оптимизировать подход к манипуляциями длиной(так как складывать 2 числа конечно же проще чем перелопатить 2 строки по 4 гигабайтика каждая...)

С другой стороны паскалевский подход имеет существенный минус - явное ограничение на длину строки, что в результате может вылиться в проблемы с переносимостью. Вообщем С и Юникс проектировали далеко не недалекие дураки, не читавшие Вирта и сделавшие нечто  "жутко неудобное". В подобных случиях - ищите женщину причину.
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Edd.Dragon

#124
Цитата: beep_boop від 01 Березень 2008, 01:20:17
А сейчас что-то изменилось?
Старое виндовое API? Осталось прежним. А в C++ уж давно все юзают string, т.е. вектор символов.

Цитата: beep_boop від 01 Березень 2008, 01:20:17
Не согласен.
У реализации паскалевкого подхода к строкам есть существенные недостатки при сомнительных преимуществах.
Затратность вычисления длины строки в С - довольно спорный вопрос.
  - Длину строки далеко не всегда необходимо знать
Менеджеру памяти ее знать просто таки обязательно. Если ты сам управляешь памятью, то тогда это будет необходимо тебе.

Цитата: beep_boop від 01 Березень 2008, 01:20:17
С другой стороны паскалевский подход имеет существенный минус - явное ограничение на длину строки, что в результате может вылиться в проблемы с переносимостью. Вообщем С и Юникс проектировали далеко не недалекие дураки, не читавшие Вирта и сделавшие нечто  "жутко неудобное". В подобных случиях - ищите женщину причину.
"Машина зверь, но собаки дико устают!  :(" (с)

Так и тут. Сишные строки - это идеальное решение 20-тилетней давности для возможностей и объемов работ 20-10-летней давности. А зачем же совеременный Камаз тащить все теми же собаками при этом получая кучу гемороя? Я прекрасно понимаю, что используя сишные строки, я смогу минизировать все операции с ними. И точно так же понимаю, что чем больше буду масштабировать и дублировать эту работу тем больше глюков получится в результате, которые потом искать ой как трудно будет! Так в чем же моя логика, если я отказался от готового (или своего) решения, которое предоставляет мне кучу удобств, упрощает код и делает его более прозрачным, автоматически избавляет от сугубо человеческих ошибок (забыл ноликом завершить, залез на чужое и т.д.).

Цитата: beep_boop від 01 Березень 2008, 01:20:17
С другой стороны паскалевский подход имеет существенный минус - явное ограничение на длину строки, что в результате может вылиться в проблемы с переносимостью.
string - это уже давно не строка с однобайтовой длиной. string = AnsiString - строка с длиной типа integer, точно так же как и в C++

Цитата: beep_boop від 01 Березень 2008, 01:20:17
Вообщем С и Юникс проектировали далеко не недалекие дураки, не читавшие Вирта и сделавшие нечто  "жутко неудобное". В подобных случиях - ищите женщину причину.
STL с ее шаблонами векторов, списков, мапов и т.д. совершенно аналогично проектировали те же самые недураки ;) А строки в Дельфи - это не подход, а иная реализация таго же самого подхода - динамического вектора.

snegoviK

#125
Цитата: edd_k від 01 Березень 2008, 13:07:38
Старое виндовое API? Осталось прежним. А в C++ уж давно все юзают string, т.е. вектор символов.
Менеджеру памяти ее знать просто таки обязательно. Если ты сам управляешь памятью, то тогда это будет необходимо тебе.

Был спор на эту тему в #c++. Впринципе, string быстро работает, но в некоторых случаях она всё равно медленнее char *. В некоторых программах нужен просто способ содежать массив символов и для этого string слишком сложная структура.

Также иногда требуется compatibility c определёнными функциями или даже с каким-то старым С-кодом. Впринципе, 80-90% случаев std::string - правильный выбор, но char * иногда тоже отлично подходит.

Edd.Dragon

Цитата: snegoviK від 01 Березень 2008, 13:19:01
Был спор на эту тему в #c++. Впринципе, string быстро работает, но в некоторых случаях она всё равно медленнее char *.
Бесспорно, но заметно ли это хоть немного на глаз в программах, в которых "нужен просто способ содежать массив символов"? Чтобы заметить разницу, нужно интенсивно оперировать огромными массивами строк, при чем не просто выделяя и удаляя их. А в таком случае использовать голый,, не обернутый char* - это выйти под пули глюков без бронижелета. Да, если каждый шаг тщательно продумывать и тратить на кажду строчку в 2 раза больше времени и на тестирование тоже, то можно будет предположить, что нигде не закралось досадной ошибки, которая вылезет в самый неудобный момент года через два. Но оно того стОит?

Цитата: snegoviK від 01 Березень 2008, 13:19:01
В некоторых программах нужен просто способ содежать массив символов и для этого string слишком сложная структура.
Вот в тут и проявляется преймущество строк Дельфи, т.к. в Дельфи это встроеный тип, т.е. и является тупо способом хранить массив символов.

Но не смотря на то, что в С++ строки - это экземпляры классов, в любой серьезной конторе будут давать по рукам за использование вместо него небезопасных типов. Качество, надежность кода и эффективность процесса разработки в современных проектах стоят гораздо выше экономии лишних килобайт и миллисекунд ;)

Цитата: snegoviK від 01 Березень 2008, 13:19:01
Кстати, я думаю, вы знакомы с недостатками структуры std::vector? Ну тогда, я думаю вы понимаете, что эти недостатки также присущи std::string. Например, в случае append to front с длинными строками, string не очень хорошо подходит.
А что изменится при управлении памятью строк вручную?  ???

snegoviK

#127
Насчет последнего параграфа. Я его удалил из оригинального поста, т.к. несовсем уверен что std::string использует std::vector. Нигде инфы описывающей контейнер для std::string я не нашел. Кое-кто мне сказал, что в gcc контейнер std::string просто char *. Я хз, честно говоря, потому я упущу этот аргумент.

Цитата: edd_k від 01 Березень 2008, 13:36:11
Бесспорно, но заметно ли это хоть немного на глаз в программах, в которых "нужен просто способ содежать массив символов"? Чтобы заметить разницу, нужно интенсивно оперировать огромными массивами строк, при чем не просто выделяя и удаляя их. А в таком случае использовать голый,, не обернутый char* - это выйти под пули глюков без бронижелета. Да, если каждый шаг тщательно продумывать и тратить на кажду строчку в 2 раза больше времени и на тестирование тоже, то можно будет предположить, что нигде не закралось досадной ошибки, которая вылезет в самый неудобный момент года через два. Но оно того стОит?

Да просто здравый смысл. Если структура данных предлагает мне 10000 функций из которых я буду использовать 2, то зачем мне такая структура? И еще, в чем проблема иногда использовать небезопасные типы/функции? Особенно, если я знаю про опасности использования? Может еще скажете, что printf зло и в серьезных конторах дают по рукам за использование этой функции вместо std::cout? Ведь, если рассуждать прогрессивно f/s/printf - небезопасные функции.

Fear of char * is superstition! Вот моё мнение.

Edd.Dragon

Цитата: snegoviK від 01 Березень 2008, 14:19:36
Насчет последнего параграфа. Я его удалил из оригинального поста, т.к. несовсем уверен что std::string использует std::vector. Нигде инфы описывающей контейнер для std::string я не нашел.
Дык h-файлы посмотри :) Вектор символов, так что все ок, ты не ошибся. И то, что тебе сказали - тоже правда, т.к. vector<T> - это обертка для T* (не для самого указателя, а для всего массива ессесно).

Цитата: snegoviK від 01 Березень 2008, 14:19:36
Да просто здравый смысл. Если структура данных предлагает мне 10000 функций из которых я буду использовать 2, то зачем мне такая структура?
Ну во-первых, не 10 000, а во-вторых, комилятор вырежет все, что не будет заюзано ;)

Цитата: snegoviK від 01 Березень 2008, 14:19:36
И еще, в чем проблема иногда использовать небезопасные типы/функции?
Временно - никаких проблем. Те же константы например. А вот если мне нужно в функции взять где-то строку, что из нее почерпнуть и выкинуть? Какой смысл мне выделять под нее память, освобождать. Основной блок брать в try ... catch, в котором продублировать освобождение? Неужели это оправдано нежеланием использовать string? При чем, вышеописаный пример предполагает, что я знаю заранее сколько выделять. В общем, почти во всех типичных задачах гемор и усложнение кода.

Зато если я знаю, что собираюсь прочесть из файла надцать строк по надцать символов и затем ничего особо менять не буду - тогда да, можно и без string обойтись. Только try catch главное не забыть.

Цитата: snegoviK від 01 Березень 2008, 14:19:36
Особенно, если я знаю про опасности использования?
Знаю, но в попыхах 1 раз из надцати использований что-то да забываю, тратя потом лишнее время на отладку.

Цитата: snegoviK від 01 Березень 2008, 14:19:36
Может еще скажете, что printf зло и в серьезных конторах дают по рукам за использование этой функции вместо std::cout? Ведь, если рассуждать прогрессивно f/s/printf - небезопасные функции.
scanf не безопасные. printf по фигу.

Цитата: snegoviK від 01 Березень 2008, 14:19:36
Fear of char * is superstition! Вот моё мнение.
Fear (основаная на личном же геморое) of non-safe char* ;) Safe char* никакой боязни не вызывает!

snegoviK

#129
Я скорее говорю о более простых ситуациях, когда std::string действительно оверкилл. 90% времени я использую std::string. Иногда просто char * как-то больше нравится. :)

Впринципе, я согласен с вашим мнением. Я просто хотел сказать, что не нужно откидывать char * полностью.

βεερ_βooρ

Поскольку основную дискусию я пропустил, то ограничусь 5 коп.:
Цитата: edd_k від 01 Березень 2008, 14:53:28
scanf не безопасные. printf по фигу.
printf по-фигу?
printf(str);
Уже страшно? :)
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Богдан

#131
Вопрос о безопасности данных (РНР).

Сейчас я пишу двиг для своего сайта. Все вроде нормально, кроме большущих дыр в безопасности:-)

Для своего же удобства я сделал инсталлер. Он запрашивает инфу для доступа к базе данных (сервер, название базы, логин и пароль), пароль для входа в админку и пароль доступа к инсталлятору.

Как он действует: после отправки GET-запроса проверяет пароль доступа к инсталлеру (мд5 которого лежит прямо в коде скрипта), создает таблицу в указанной базе данных и вставляет туда мд5 пароля от админки (в эту же таблицу по ходу будут записываться настройки и разные записи). После чего записывает данные доступа к базе в файл.

Тут-то и начинаются проблемы.

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

Как залатать эту дыру?

Да, еще хочу спросить, безопасно ли хранить хеш пароля прямо в скрипте как переменную?
И как убрать пароль из query string после отправки запроса (т.е. после знака вопроса в адресной строке браузера)?


snegoviK

#132
Во-первых, MD5 сама по себе уже не безопасна. Пока что серьёзные взломы MD5 проходили только внутри учебных заведений и информация не разглашалась (я как-то писал в блоге о недавнем случае), но я бы задумался об альтернативах и возможных усовершествованиях при создании новых проектов. К сожалению, более "продвинутая" SHA1 тоже была хакнута, так что "обычным смертным", которые просто хотят написать сайт не для массового использования остаётся либо использовать комбинации MD5 + SHA1, либо одну из них, что я бы назвал небезопасным выбором.

Как сделать сайт безопаснее? Зашифрованное подключение типа SSL/TLS (у PHP есть библиотека OpenSSL). Пока что эта технология нареканий не вызывает, потому если хочется попробовать создать максимально защищенный веб-сайт из технологий, которые имеем на сегодняшний день, я бы рекомендовал посмотреть как создать зашифрованное соединение. Сам я никогда этим не занимался потому не скажу точно сложно ли это, что нужно и сколько времени займёт. Если все же решишь глянуть OpenSSL, настоятельно рекомендую почитать немного о принципе работы этой защиты, чтобы понимать от чего она защищает, как и что хакер должен сделать, чтобы обойти эту защиту (cм. вложение). Это поможет в дальнейшей разработке.

Более тривиальная защита в твоём случае:

1) Не нужно вставлять пароль в URL. Например, альтернатива, вместо $_GET, сделай простой файл с формой и забирай пароль используя $_POST (или еще есть $_REQUEST, который делает $_POST, $_GET и $_COOKIE).
2) В сорсе храним пароли по умолчанию в виде MD5 кэша (это нормально).
3) Ставим лок на директорию Apache, даём доступ в эту директорию только от имени пользователя, который занимается запуском PHP скриптов на твоей машине, посылаем на фиг всех умных, которые хотят её скачать. Directory Listing тоже ессесно блочим. Снова же, я в администрировании Apache шарю на уровне нуба, потому точных инструкций дать не могу, но точно могу сказать что защитить сервер от атак здраво настроив доступ в определенные директории на Apache можно 100%.

ЗЫ. Прикрепил конспект со 2-го курса по введению в безопасность сети, т.к. облом искать что-либо путное. :) Я кстати, не совсем уверен есть ли у меня право на распространение конспекта или нет... Будет считать, что есть. :)


[вложение удалено ради получения свободного места]

Bismark

Цитата: Богдан від 06 Березень 2008, 10:38:37
Как он действует: после отправки GET-запроса проверяет пароль доступа к инсталлеру
Яка ж може бути безпека, коли пароль відправляється у "відкритому" вигляді GET-запиту? ???

dojik

Посоветуйте хорощий сайт с описанием принципов создания утилит, а то от игр никакой пользы, а хочется чего-нибудь серьезного. ???
На бейсике или паскале. ;)
З.Ы. Кстати, многие говорят, что лучше бросить бейсик. За что посоветуете взяться? :(

Bismark

Цитата: dojik від 08 Березень 2008, 13:37:39
З.Ы. Кстати, многие говорят, что лучше бросить бейсик. За что посоветуете взяться? :(
Зараз тобі нарозказують, що С/С++ рулить і все таке :)
Якщо знаєш Паскаль (Делфі) то його можно цілком застосувати для нормальних програм.
Хочеш кросплатформеність - вивчи С# або Яву.
А якщо треба писатисвіруси чи дебагери - вчи Асм :)

Anton T.


Богдан

#137
Худо-бедно таки дописал инсталлер.

Цитата: snegoviKНе нужно вставлять пароль в URL. Например, альтернатива, вместо $_GET, сделай простой файл с формой и забирай пароль используя $_POST (или еще есть $_REQUEST, который делает $_POST, $_GET и $_COOKIE).

Пробовал отправлять данные из формы через POST, но в URL всё равно была Query String. Может я неправильно понял? SnegoviK, что ты имел ввиду?

Я решил совместить форму и скрипт, а данные отправлять через GET. Так намного удобнее обрабатывать и выводить сообщения об ошибках.

В итоге, получился такой нормальный и функиональный инсталлер (а главное — о чудо, — он верно работает:-), вот только все еще очень напрягают пароли в Query String.



Еще раз повторю, этот скрипт я пишу для себя, распространять свою CMS-ку не буду:-) И по идее только я буду его видеть, так что мне не нужна суперзащита пересылаемых данных.

Bismark

Цитата: Богдан від 08 Березень 2008, 20:15:15
Пробовал отправлять данные из формы через POST, но в URL всё равно была Query String. Может я неправильно понял? SnegoviK, что ты имел ввиду?
Взагалі то при використанні POST у запиті не повинно бути ніяких параметрів, тобто там повинен бути вказаний лише сам файл, на який веде посилання, наприклад index.php без усяких "?" і т.д.

Богдан

Цитата: Bismark від 08 Березень 2008, 20:55:58
Взагалі то при використанні POST у запиті не повинно бути ніяких параметрів, тобто там повинен бути вказаний лише сам файл, на який веде посилання, наприклад index.php без усяких "?" і т.д.
Ой... Тогда я что-то напутал:-)

Bismark

Цитата: Богдан від 08 Березень 2008, 21:17:48
Ой... Тогда я что-то напутал:-)
Просто запиши щось таке:

<form action="index.php" method="POST">
***
</form>

snegoviK

#141
2 Богдан. Вот пример:


<?php
   
//some includes go here
  
include ("my_include.php");
?>

<body>
<!-- форма перезагружает страницу при нажатии кнопки Submit -->
<FORM NAME ="form1" METHOD ="POST" ACTION = "name_of_this_page.php">

<!-- наше поле, из которого мы хотим взять данные -->
<INPUT TYPE = "Text" Name = "YourField">
<!-- сама кнопка Submit -->
<INPUT TYPE = "Submit" Name = "Submit" VALUE = "Fetch">

</FORM>

<?php
   
// при загрузке страницы проверяем есть ли что-то в нашем поле
  
if(isset($_POST['YourField']))
  {
      
// если есть мы проводим какие-то операции
    
$var do_some_stuff$_POST['YourField'] );
  }
?>

</body>


GET удобен для динамической генерации контента, где публичный доступ к аргументам не опасен.

Например, show_logs.php?y=2007&m=12&d=5&h=22&m=19. То есть, пользователь просматривает логи через какую-то GUI оболочку, которая выставляет агрументы для какой-то функции в show_logs.php. Но если пользователь сам решит менять аргументы в адресной строке браузера ничего не изменится.

IK91

У меня возникла следуююшяя проблема : написана сетевая библиотека построел я ее на Winsock2,  но изначально писалась в среде Builder 6.0, теперь я ее перенес на visual studio , не много подправили исходный код и она отлично скомпилировалась и слинковалась в common.lib, теперь я ее пытаюсь использовать в своем DLL, подрубил хэдера и сам либ, объявил объект одного из класса из библиотеки, пытаюсь скомпилить компиляция идет нормально, но ликовщик спотыкается и пишет uresolved token ну и в пару ему unresolved external symbol   ! Что делать не знаю хоть головой об стенку бейся , ОЧЕНЬ надеюсь на вашу помошь ! :'(
Звонишь мэру в офис, и он высвечивает сигнал в небе, в виде <мораль не позволяет>.

snegoviK

#143
То есть, вы уверены, что настройки VS проекта (Library Directory, Using Libraries, etc.) правильные?

IK91

Цитата: snegoviK від 09 Березень 2008, 16:32:37
То есть, вы уверены, что настройки VS проекта (Library Directory, Using Libraries, etc.) правильные?
Да уверен ! Но мне уже помголи оказалось не хватало ссылки на библиотеку ! Но всёровно всем спс кто хотел мне помочь !
Звонишь мэру в офис, и он высвечивает сигнал в небе, в виде <мораль не позволяет>.

dojik

Цитата: Bismark від 08 Березень 2008, 14:25:07
Зараз тобі нарозказують, що С/С++ рулить і все таке :)
Якщо знаєш Паскаль (Делфі) то його можно цілком застосувати для нормальних програм.
Хочеш кросплатформеність - вивчи С# або Яву.
А якщо треба писатисвіруси чи дебагери - вчи Асм :)
Дякую, для себе вирішив взятись за Яву...(... значить, що все ще попереду ;))

Edd.Dragon

Цитата: dojik від 08 Березень 2008, 13:37:39
З.Ы. Кстати, многие говорят, что лучше бросить бейсик. За что посоветуете взяться? :(
C# - если хочешь удобство (в плане разработки) и сравнительную безопасность кода (в смысле вылетов по невнимательности).

C++ - если готов контролировать все сам и помнить разные ньюансы, ну или собираешься программить под Линуксом.


Цитата: Bismark від 08 Березень 2008, 14:25:07
Якщо знаєш Паскаль (Делфі) то його можно цілком застосувати для нормальних програм.
Хочеш кросплатформеність - вивчи С# або Яву.
Если знаешь Дельфи, который уже не развивается и хочешь перейти на Visual Studio, то C# будет идеальным вариантом (кроссплатформенность пока что достоинством считать не стОит). В плане удобства среды разработки и принципов разработки С# и Дельфи - братья. А вот особенности Студии при разработке на C++ практически не изменились с прошлых версий и при переходе с Дельфи ощущаешь некоторый дискомфорт - то того не хватает, то этого, то автоматика ведет себя как-то коряво. Только переключаешься в C#-проект - среда та же, а все по-другому.

Так что, для новичков или привыкших к Дельфи C# или Ява предпочтительнее независимо от кроссплатформенности.

βεερ_βooρ

Цитата: edd_k від 14 Березень 2008, 10:39:37
C++ - если готов контролировать все сам и помнить разные ньюансы, ну или собираешься программить под Линуксом.
Гон. Никто на С++ программить под Линуксом не заставляет. Наоборот свобода творчества в виде солидной подборки компиляторов/интерпретаторов в стандартной поставке большинства дистрибутивов присутствует.

ЗЫ Ну и за shell не забываем.
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Nikolai

Позвольте вставить свои 5 копеек холивора, С++ рулит :).
If you do what you have always done, you'll get what you have always got

βεερ_βooρ

Цитата: Nikolai від 15 Березень 2008, 18:58:56
Позвольте вставить свои 5 копеек холивора, С++ рулит :).
С++ холивор закончился 2 недели назад ;D
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?