На главную страницу
Форум txt.version   

Статья :: Surveys Online!


by Dave Taylor

Dave Taylor is the president of interface design firm Intuitive Systems and author of many best-selling books on UNIX and Web page design. He's also CTO of The Internet Mall, the largest shopping site on the Net.

Surveys Online!

I'd like to show a very simple solution that you can expand to create a pretty cool new area on your Web site: an online survey system.

The basic idea is simple: a Web page includes a survey question that's really a form, and the answer is added to a log file that contains the combined answers from all survey takers. To display the survey results, you simply open up the log file, tally all the yes and no answers, and display them on the screen.

The HTML Frontend

The core of the HTML that you need to ask the survey question is shown here:

<FONT ><B>Take Our Simple Survey!</B></FONT>
<B>I think that watching television improves your mind:</B>
<form method=get action=take-survey.cgi>
<input type=radio name=answer checked value=T> Yes
<input type=radio name=answer value=F> No
<input type=submit value="tally my answer">

Note that if you strip out all the formatting, the entire form boils down to a five line form:

<form method=get action=take-survey.cgi>
<input type=radio name=answer checked value=T> Yes
<input type=radio name=answer value=F> No
<input type=submit value="tally my answer">

This appears on screen as shown in figure 1.

This is the simplest of all possible surveys, of course; a single question and two possible answers, true or false. (Well, in this case it's yes and no, but the concept is the same!)

Nonetheless, it's an easy little device you can use to add some interactivity to an existing page. Sites like Parent Soup <http://www.parentsoup.com/> use it to very good effect.

Receiving the Survey Answer

To receive the survey, the resultant CGI program ­ in C as usual ­ is straightforward because we're insisting on using the METHOD=GET, which ensures that the answer is passed in the QUERY_STRING variable, and because we don't have to parse the resultant value.

When the user clicks on the "tally my answer" button, the URL that is built looks like:


which means that the QUERY_STRING variable looks like:


so it's a simple step of getting the QUERY_STRING variable then looking at the eighth letter to see if it's a T or F, as you can see in the code snippet below:

 char answer, *cp;

 if ((cp = getenv("QUERY_STRING")) == NULL)
  error("no query string?");

 answer = (*(cp + 7) == 'T'); /* test the first character only */



In this case, as with many other CGI programs I develop, I've opted to have an error() routine that displays to the user the specified message and then immediately exits from the script. Makes handling errors quite a bit easier.

With this code, the only way that you can see the answers to the survey are to answer it yourself, which isn't necessarily the best way to code this. An easy addition here would be to indicate that a zero-length QUERY_STRING simply shows the results instead of the error message, which you'd accomplish by changing the above code to the following:

 char answer, *cp;

 if (((cp = getenv("QUERY_STRING")) == NULL) ||
   strlen(cp) == 0)

 answer = (*(cp + 7) == 'T'); /* test the first character only */


I am taking advantage of one trick here: on a conditional statement that has a logical OR between its expressions (a || b) the second expression isn't evaluated if the first is true. This means that we don't have to worry about the situation where the getenv() returns a NULL that we then feed to the strlen() function. If you have any weirdness with this CGI script, this is a likely spot for the problem!

Adding the Answer to the Log File

Once you have the answer as either true or false (1 or 0, of course), you need to open and append it to the log file. This is done with:

char answer;
 /** append the user answer to the survey **/

 FILE *fd;

 if ((fd = fopen(LOGFILE, "a")) == NULL)
  error("couldn't open log file");

 fputc(answer? 'T' : 'F', fd);


I could directly write the value of answer in the log file, as a 0 or 1, but it would take up more space (each would be an int) and it'd be impossible to edit or view with regular UNIX utilities. Instead, the inline conditional answer? 'T':'F' evaluates to the 'T' character if the answer is 1, and 'F' if answer is 0.

Because of how most servers have the permissions set, you'll probably need to create the log file with the touch command and make sure it has permission so that your CGI scripts (which will probably run as user Web, WWW, or similar, rather than you) have permission to append. I use chmod 777 *.log to solve the problem, making sure that the directory is mode 755 to avoid too much trouble.

Showing the Results

Once you have a growing log file, you unquestionably want to show survey takers the answers compiled so far. That's done with the show_results() routine:

 FILE *fd;
 int answerstring[2];
 char ch;

 answerstring[0] = answerstring[1] = 0;

 if ((fd = fopen(LOGFILE, "r")) == NULL)
  error("no log file to show results?");

 while ((ch = fgetc(fd)) != EOF)
  answerstring[(ch =='T')] ++;

 printf("Content-type: text/html\n\n");

 printf("<BODY BG>\n");
 printf("<CENTER><font ><B>Survey\
          Ans wers</B></font></CENTER>\n");

 printf("Answers so far:<p>\n");
 printf("%d answered TRUE<br>\n", answerstring[1]);
 printf("%d answered FALSE<br>\n", answerstring[0]);


Here you can see that the file is read and tallied each time, with the true and false answers stored in the answerstring array. Also note that the usual "Content-type: text/html" must be output before any of the HTML is produced, as always.

The final routine to see here is the error function:

char *string;
 /** show the error in a reasonably cool format **/

 printf("Content-type: text/html\n\n");

 printf("<BODY BG>\n");
 printf("<h2>Error Encountered:</h2>\n");
 printf("<H3>%s</h3>\n", string);


This is a very primitive solution, but you can see the skeleton of how to create a quite sophisticated online survey system, one that can display the results as percentages, bar graphs, you could even have a pie chart if you were motivated!

The biggest problem with this, however, isn't that the results are displayed as boring text ­ which isn't too horrible ­ but rather that the results don't reiterate the original question. This is a major drawback of this solution and one that can only be solved by either having the take-survey CGI program sneak into the HTML source of the page and dig out the question (which would be tricky) or to have the question itself ­ and perhaps its possible answers ­ stored in a separate file.

The latter solution sounds good, except: if you want to have the survey on a static Web page, perhaps your home page, then you end up with the survey question in two places ­ that page and the info file ­ with all the usual challenges for ensuring they're consistent.

If the survey page is dynamic, of course, it can very easily read the same data file that is used to display a nice answer, which solves a lot of the problem. In fact, you can see this exact strategy (albeit with a slightly different application) at work online at <http://www.intuitive.com/origins/> where a shared data file contains both the question, possible answers, and the correct answer for each of the many questions in the game.


Surveys Online!

страницы в данном разделе 
 Using Assembly Language in Linux.  "Разрешение монитора" выворачиваем на изнанку
 Активный сервер Web: расширения CGI  Скопировать файл построчно
 Побайтное копирование файла  HTML Encyclopaedia
 Первая программка  показывает данные принятые от GET запроса
 Выводит случайную картинку  Примеры небольших программ
 Записывает в файл Host, REMOTE_HOST, HTTP_USER_AGENT и выводит картинку  Программа, совмещающая команды mv и cp.
 POST запрос url decode  Выводит QUERY_STRING
 Показывает переменные окружения сервера  Показывает время на сервере
 Изменение размера файла  Surveys Online!
 URL DECODE  Перенаправляет в зависимости от юзер агента
 Показывает юзер агент и хост   

Околокомпьютерная литература (375)
Программирование (102)
Программы (75)
ОС и Сети (49)
Интернет (29)
Аппаратное обеспечение (16)
Базы данных (6)

Содержание сайта (выборка)
Протоколы TCP/IP (принципы, протоколы и архитектура)

JavaServer Pages (JSP)

Базы данных
Основы mysql
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI

©  programming-lang.com  справочник программиста