Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 6
На сайте нет зарегистрированных пользователей

Пользователей: 13,361
новичок: uehuat
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Информационная система - продуктовый магазин на Turbo Pascal (База данны...
Файл записей с выводом обратного заголовка на Turbo Pascal
База данных - словарь терминов на Delphi + Пояснительная записка

Веб-программирование на Cи

В результате этих нехитрых операций вместо "a" будет напечатано "b". Код символа рассматривается как целое число и увеличивается на 1. Этот принцип можно использовать при преобразовании строчных латинских букв в заглавные (с буквами русского алфавита так не получится). Определив массив символов buf[20] в 20 символов длиной, мы зарезервировали под него место, в которое можем разместить 20 символов. При объявлении buf[] мы только обозначаем, что будем использовать переменную buf для обращений к массиву символов. Места под сам массив мы не отводим. То есть место мы отвели, но под указатель — переменную, которая будет хранить адрес массива символов. Следовательно, buf[20] отводит место под массив и под указатель на него. Однако, как же быть со строками символов? Ведь все переменные окружения — это строки символов. Для работы с ними используются функции, которые описаны в include-файле string.h:
strcmp() — сравнение строк
strcpy() — копирование строк
strstr() — поиск подстроки



и т.д.При этом строка распознается по символу '\000' в конце строки, т.е. все разряды байта или совокупности байтов, в которой расположен символ, равны нулю. Приведем пример копирования QUERY_STRING в массив символов query:
#include
#include
void main()
{
char query[1024];
strcpy(query,getenv("QUERY_STRING"));
printf("Content-type: text/plain\n\n%s\n",
query);
}



Функция strcpy() копирует строку запроса из переменной окружения QUERY_STRING в переменную query и после нее дописывает символ '\000'. Мы заранее отвели побольше символов под массив query, т.к. strcpy не проверяет границ массива, и при такой операции можно запросто "наехать" на область памяти, не отведенной под наш скрипт, что приведет к его аварийному завершению (segmentation violation — как это знакомо). Поэтому лучше контролировать размеры буферов и использовать указатели.

Указатели

Указатели — это наиболее мощное и одновременно опасное средство программирования в С. В современных языках, таких как Java, например, указатели уничтожают как класс, т.к. именно они — основной источник множества ошибок, а, точнее, манипуляции с ними. С другой стороны, нельзя написать эффективной программы (быстро исполняется и занимает мало памяти), если не использовать указатели и адресную арифметику, которая позволяет манипулировать указателями. Указатель на переменную определенного типа данных объявляется путем ввода символа "*" перед именем переменной:
int *n;
char *query;


При этом место резервируется под адрес соответствующего значения. В Intel-платформах существуют модификации указателей в зависимости от модели памяти (т.е. какой длины адрес должен использоваться — 16 бит, 24 бита или более). В 64-разрядных архитектурах просто указывается опция компилятора (например, в Irix 6.4 "-64" — длинные адреса для всей программы или "-32" — короткие адреса). С указателями при программировании CGI-скриптов приходится сталкиваться постоянно. Указатель на переменную окружения возвращает функция getenv(). Другими словами, она возвращает адрес начала значения переменной окружения:
char *length;
length = (char *) getenv("CONTENT_LENGTH");


Другой пример — указатель на массив переменных окружения и массив аргументов командной строки:
#include
#include
void main(argc,argv,env)
int argc;
char *argv[];
char *env[];
{
/* тело программы */
}



В данном случае конструкция типа *argv[] — это массив указателей, которые указывают на символы, а точнее, на символьные переменные. В данном контексте совсем по-другому смотрится конструкция char a[] — это просто иная форма записи указателя. Переменная a — это указатель на массив. Есть, правда, один нюанс. Он заключается в том, что, обращаясь к элементам массива, перемещаться мы будем на длину элемента массива, а это уже зависит от типа данных.

Управление потоком вычислений

С представляет собой универсальный язык программирования со всеми присущими подобным языкам атрибутами. Он родился в период увлечения структурным программированием, поэтому в нем есть операторы, которые позволяют построить программу без использования goto. Из всех механизмов управления ветвлением программы и передач управления мы рассмотрим несколько:
оператор if;
оператор goto ;
оператор while ;
оператор for ;
оператор switch ;
оператор break.



В целом этого набора должно хватить для программирования CGI-скриптов.
Оператор if



Условное исполнение части кода программы в С определяется оператором if. В общем случае он имеет синтаксис:
if(условие) оператор; [else оператор;]или
if(условие) { тело_блока }
[else { тело_блока }]


В этой записи "условие" — это логическое выражение, которое возвращает значения "истина" или "ложь", например, "x>y".
Оператор в данном контексте — это простой оператор С, например, "x=1". Блок — это совокупность простых операторов и/или блоков. Самый простой пример применения if — определение метода доступа к CGI-скрипту:
char *query;
int n;
...
if(strcmp(getenv("REQUEST_METHOD"),"GET"))
{
query = getenv("QUERY_STRING");
}
else
{
n = atoi(getenv("CONTENT_LENGTH"));
query = (char *) malloc(n+1);
memset(query,'\000',n+1);
fread(query,n,1,STDIN);
}



В данном случае в качестве условия используется функция сравнения двух строк. Если результат сравнения – "истина", то исполняется первый блок (запрос из переменной окружения QUERY_STRING), если результат сравнения – "ложь", то считываем запрос из стандартного ввода скрипта. Оператор goto
Сколько было возражений против использования goto, но он до сих пор существует в большинстве языков программирования. В простых программах, по большому счету, без него можно обойтись, но в ряде случаев он необходим. Оператор goto — это принудительный переход на другой фрагмент кода программы. Например, при разных алгоритмах обработки выхода из цикла:
...
for(i=0;i {
buf[i]=getc();
if(buf=='\n') goto STRING;
}
printf("В потоке ввода одна строка\n");
STRING:printf(
"Одна строка считана из потока ввода\n");



...В данном случае переход осуществляется при обнаружении символа конца строки во входном потоке. Оператор while
Оператор while позволяет исполнять тело цикла до тех пор, пока верно условие. Например, при распечатке переменных окружения:
#include
#include
void main(argc,argv,env)
int argc;
char *argv[];
char *env[];
{
int i;
i=0;
while(env[i])
{
printf("%d:%s\n",i,env[i]);
i++;
}
}



В данном случае программа распечатывает переменные окружения до тех пор, пока указатель env[i] не примет пустое значение. Оператор for
Оператор for — это детализация общего случая оператора цикла. Он состоит из блока инициализации переменной цикла, условия исполнения тела цикла и блока операторов конца цикла. Самой простой и наиболее распространенной его формой является случай одной переменной цикла:
for(i=0;i {
/* тело цикла */
}



При программировании CGI-скриптов с оператором цикла можно познакомиться при распечатке аргументов командной строки в запросах типа ISINDEX:
#include
#include
main(argc,argv,env)
int argc;
char *argv[];
char *env[];
{
int i;
printf("Content-type: text/plain\n\n");
for(i=0;i {
printf("argv[%d]=%s\n",i,argv[i]);
}
}



В данном случае переменная цикла пробегает значения от 0 до значения переменной argc, которая содержит число аргументов командной строки. Оператор switch
Оператор switch — это переключатель на несколько положений, если пользоваться терминологией электротехники. Аргумент может принимать некоторые значения, например целочисленные или символьные, а выполняться будет тот фрагмент кода, который описан для этого значения:
switch(x)
{
case 'a': x='A'; break;
...
case 'z': x='Z'; break;
}



Данный фрагмент кода позволяет все строчные буквы превратить в заглавные.

Оператор break

Оператор break применяется для досрочного завершения цикла, в котором он указан. В некотором смысле он заменяет оператор goto. В примере с оператором switch оператор break использовался для выхода этого оператора из блока. Если бы break там не применялся, то операторы блока исполнялись бы последовательно с точки входа в блок до конца блока. Оператор continue
Оператор continue применяется для пропуска операторов цикла, непосредственно следующих за оператором continue до конца цикла. В программировании CGI-скриптов оператор можно применять для обхода операторов вывода по условию, например, по IP-адресу удаленного хоста:
while(buf = fgets())
{
if(!strncmp("144.206.160.32",
getenv("REMOTE_ADDR"),14)) continue;
...
}



В данном случае дополнительные операторы будут выполняться только для пользователей компьютера с IP-адресом 144.206.160.32.
Файлы
В С принята поточная модель файла данных. Она предполагает, что файл рассматривается как поток байтов. Операции чтения и записи файла опираются на понятия начала потока (первый байт), конца потока (последний байт) и текущей позиции в потоке (последний считанный/записанный байт). При открытии файла на чтение или запись с ним связывается дескриптор потока данных. Он указывает на структуру данных, в которой хранится необходимая для работы с файлом информация. Место под эту структуру отводится динамически, т.е. в момент исполнения программы. Для того, чтобы избежать "утечки" памяти, файлы после их использования следует закрывать. Для начала работы файл нужно открыть:
FILE *IN;
...
IN = open("text.txt","r");


Объявление (декларация) FILE *IN; определяет переменную IN как указатель на структуру дескриптора файла. Функция open() присваивает указателю IN значение адреса дескриптора файла с именем text.txt. При этом файл открыт только для посимвольного чтения. Если нужно открыть файл для записи, то вместо r следует указать w. Если требуется и чтение, и запись в файл, то его открывают со значением второго аргумента (вместо r) равным r+. После работы с файлом его нужно закрыть:
FILE *IN;
...
IN = open("text.txt","r");
...



close(IN);Закрывается файл функцией close(). При этом происходит освобождение памяти из-под структуры дескриптора файла и буферов ввода/вывода, которые были созданы при открытии файла. Желательно закрывать файлы в обратной последовательности (последним закрывается файл, который был открыт первым). Это позволяет избежать фрагментации памяти. Для чтения данных из файла можно использовать функцию fread(): FILE *IN;
char query[1024];
...
IN = open("text.txt","r");
fread(query,1024,1,IN);
...



close(IN);В данном случае в массив символов query считывается один блок данных размером 1024 символа из файла, связанного с дескриптором IN. Если числа 1024 и 1 поменять местами, то функция read считает 1024 блока по одному символу. Для записи в файл применяется другая функция — fwrite():
FILE *OUT;
...
OUT = open("text.txt","w");
fwrite(query,1024,1,OUT);
...



close(OUT);Значения параметров в этой функции те же, что и в функции fread(). Функции fread() и fwrite() — это функции неформатного ввода/вывода. В них не происходит никакого преобразования данных. Данные записываются в файлы в том виде, в котором они хранятся в переменных. Следует отметить, что в С различают два типа потоков данных: символьные и двоичные. Если fread()/fwrite() применять для двоичного потока, то, действительно, никаких преобразований происходить не будет. Если применять эти функции к символьным потокам данных, то преобразования производятся. Например, выполняется обработка конца строки. Кроме неформатного ввода/вывода, в С применяют форматный ввод/вывод. Он реализуется через функции fscanf() и fprintf(). Первая функция служит для считывания и преобразования данных, а вторая — для преобразования и записи. Примером применения этих функций может служить счетчик посещения страницы:
#include
#include
void main()
{
FILE *IN;
int n;
IN = open("text.txt","r");
fscanf(IN,"%d",&n);
close(IN);
IN = open("text.txt","w");
n++;
printf("%d",n);
fprintf(IN,"%d",n);
close(IN);
}



В данном случае целое число, записанное ASCII-символами, считывается из файла text.txt, преобразуется в формат целого числа и помещается в переменную n. После этого оно увеличивается на единицу, записывается на старое место и распечатывается в поток стандартного вывода. Если в HTML-странице разместить подстановку (server side include) результатов исполнения этого скрипта, то мы реализуем счетчик посещения страниц.

Препроцессор

Директивы препроцессора позволяют собрать программу на языке С из готовых блоков кода. Кроме того, можно реализовать управление процессом компиляции, например, разработать процедуру условной компиляции для разных операционных систем. В рамках разработки простых CGI-скриптов нам нужна будет только инструкция включения "include". Во всех примерах данного раздела она используется для включения в код программы описаний функций из набора стандартных библиотек. Если необходимо задействовать функции форматного ввода/вывода, а их мы применяем для печати в стандартный вывод, то следует использовать инструкцию #include :
#include
void main()
{
printf("Content-type: text/html\n\n");
printf("");
printf("");
printf("");
printf("");
printf("

Привет от-CGI

");
printf("");
printf("");
}



Инструкция препроцессора начинается с символа "#". При использовании инструкций включения различают локальные файлы и стандартные файлы включения. Когда применяются стандартные файлы включения, имя файла заключают в "<имя_файла>". При использовании локального файла имя файла заключают в обычные двойные кавычки — "имя_файла". В наших примерах применяются только стандартные файлы включений. Мы используем файлы включения только для ввода в код программы описаний стандартных функций и констант, с этими функциями связанных. Для наиболее распространенных функций существует файл /usr/include/stdlib.h. Его включения в программу достаточно для того, например, чтобы использовать функции ввода/вывода и сравнения строк:
#include
void main()
{
printf("Content-type: text/plain\n\n");
if(strcmp("GET",getenv("REQUEST_METHOD"))
{
printf("Нет даты в потоке STDIN");
}}



В данном случае в stdlib.h определены шаблоны для функций strcmp() и getenv(). При программировании в среде Unix программист всегда может применить команду man, которая позволяет получить подсказку по использованию той или иной функции C.

Компиляция

Программа на С — это текстовый файл, из которого программа-компилятор создает исполняемый файл. CGI-скрипт — это исполняемый файл. Для компиляции используется компилятор с языка С. В большинстве Unix-платформ этот компилятор носит название cc. Предположим, что нужно создать программу с именем hello.cgi. Код на С расположен в файле hello.c. В этом случае достаточно выполнить:
bash%cc -o hello.cgi hello.c
Опция "-о" в этой записи определяет имя исполняемого файла. Он задается сразу вслед за ней. Имя файла исходного текста С указывается просто в качестве параметра. Если в скрипте использовать функции из внешней библиотеки, то компилятору необходимо указать ее адрес:
bash%cc -o test.cgi test.c -lpq
В данном случае мы используем внешнюю библиотеку pq. Опция -l определяет имя библиотеки. Сама процедура сборки программы называется linking (связывание). Отсюда и буква "l" перед именем библиотеки.
Опубликовал Kest October 27 2008 12:41:13 · 0 Комментариев · 14282 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Страница 2 из 2 < 1 2
Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Delphi Russian Kn...
Illusion
Dnavigator
SODA [Исходник на...
Turbo Pascal for ...
3D Тетрис [Исходн...
Панель "ссылки"
XPcontrol
Голосование для ...
AlnComponents
Язык программиров...
Visual Basic for ...
Java в примерах -...
около 291 статьи ...
CarGame [Исходник...
PrevInst
Изучаем Ассемблер
SMExport
Киллер окон
EditNew

Топ загрузок
Приложение Клие... 100771
Delphi 7 Enterp... 97787
Converter AMR<-... 20259
GPSS World Stud... 17014
Borland C++Buil... 14186
Borland Delphi ... 10267
Turbo Pascal fo... 7372
Калькулятор [Ис... 5968
Visual Studio 2... 5205
Microsoft SQL S... 3661
Случайные статьи
Онлайн казино на р...
Принтеры и DTE
Задание на моделир...
Класс TMetafile
В текстовом файле ...
Узлы XPath
Тайны алхимии со с...
Выделение трех объ...
Функция ввода даты
Информация в верти...
6. Локальная групп...
Выборка и сортиров...
Что такое петлевой...
Циклические связан...
Даны m натуральных...
Типизация перемен...
Главная угроза веб...
ПРИНЦИП РАБОТЫ СИС...
Обычно при внедрен...
Игровые автоматы В...
Модифицированный чип
INCREMENT (УВЕЛИЧИТЬ)
Определяется сущес...
К головоломке "зеб...
Что отслеживает се...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?