Witam,
zwracam się z prośba o pomoc w poprawieniu programu. Muszę napisać skrypt CGI w Borland C++ Builder, który będzie wyszukiwał użytkownika w bazie danych w formacie .txt (rekordy typu - w każdej linijce pliku informacje: nazwa użytkownika, miasto, telefon, wiek oddzielane separatorem , czyli np.: KowalskiWrocław71-333-33-4437). Po przyjęciu zapytania, program ma dynamicznie generować stronę HTML z wynkiem zapytania wyświetlanym drabinką cout. Program ma umożliwiać/zawierać:
- wyszukiwanie z paska przeglądarki (np.: http://nazwa.serwera/katalog/skrypt.exe?Kowalski i to ma wyszukać odpowiedni rekord) <-- to już jest zrobione
- formularz umożliwiający dodawanie użytkownika i jego danych do bazy w pliku .txt (przy czym trzeba zaimplementować zabezpieczenie przed dodaniem użytkownika, który już istnieje w bazie)
- formularz umożliwiający wyszukanie użytkownika w bazie
- button umożliwiający pokazanie zawartości bazy w .txt (czyli po prostu skierowanie pod odpowiedni URL po kliknięciu w guzik)
Dodatkowo mam pytanie - czy zna ktoś z Was jakiś dobry darmowy serwer obsługujący CGI? Tak by można było testować działanie napisanego programu. Do tej pory korzystałem z prywatnego serwera znajomego, ale ta możliwość już niestety odpadła, a jak próbuję skorzystać z jakichś darmowych serwerów internetowych, to po umieszczeniu skompilowanego programu oraz bazy danych na serwerze i próbie wyszukiwania użytkownika albo otrzymuję komunikat, że żądany URL nie istnieje, albo spotykam się z próbą zapisania programu na dysku.
Poniżej zamieszczam kod tego, co do tej pory mam:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream>
#define UNHEX(C) \
((C >= '0' && C <= '9') ? C - '0' : \
((C >= 'A' && C <= 'F') ? C - 'A' + 10 : \
((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)))
const char * header = "Content-type: text/html\n\n<html><head><title>cgi-bin</title></head> <body bgcolor=\"#FFFF00\">\n";
const char * foot = "</body> </html>\n";
using namespace std;
main(int argc, char *argv[])
{
string query;
char * method;
ifstream plik;
int znaleziony=0; // flaga pozwalająca oznaczyć znalezienie rekordu w bazie danych
// wyświetlenie nagłówka
cout << header << endl;
// do pobierania danych ma służyć metoda get
// tutaj sprawdzamy, czy program został uruchomiony jak zwykły plik .exe
if ((method = getenv("REQUEST_METHOD")) == NULL || strcmp(method,"GET"))
{
cout << "Ten program nie służy do samodzielnego uruchamiania." << endl;
exit(1);
}
// sprawdzenie, czy program dostał jakieś dane
query = (getenv("QUERY_STRING") == NULL ? "" : getenv("QUERY_STRING"));
if(!query.empty())
{
// tu opcjonalnie można sprawdzić, co zostało zadane przez użytkownika
// cout << "Wej¶cie: "" << query << """ << "<br>" << endl;
/* zamiana kodów na znaki */
// + na spacje
while (query.find("+",0) != string::npos)
{
string::size_type pos = query.find("+",0);
query.replace(pos, 1, " ");
}
// kody z postaci %nn na znak
while (query.find("%",0) != string::npos)
{
string::size_type pos = query.find("%",0);
char c[2];
c[0] = (UNHEX(query[pos+1])) << 4;
c[0] += UNHEX(query[pos+2]);
c[1] = 0x0;
query.replace(pos, 3, c);
}
// Tu można sprawdzić poprawność dekodowania danych
// cout << "Zdekodowane wej¶cie: "" << query << """ << "<br>" << endl;
// otwarcie bazy danych
plik.open("baza.txt", ifstream::in);
if (!plik.is_open())
{
cout << "Nie można otworzyć pliku bazy danych<br>" << endl;
}
char buf[1024];
// wyszukiwanie nazwiska okreslonego parametrem w bazie rekordow
do
{
plik.getline(buf, 1024, 'n');
string e = buf;
string::size_type pos = e.find("*",0);
if (pos == string::npos && !e.empty())
{
cout << "Baza danych w nieprawidłowym formacie (przetwarzany rekord: "" << buf << "")" << endl;
break;
}
else
{
// sprawdzenie, czy wczytany rekord jest poszukiwanym
if (e.substr(0,pos) == query) // tak, to jest ten
{
/* struktura rekordu: nazwa uzytkownika*miasto*telefon*wiek
W jednej linii - jeden rekord. Wyszukiwanie jest czułe na wielkość znaków, czyli:
Jan Kowalski to NIE JEST to samo co jan kowalski */
// pobieranie pozostałych 3 pól wyszukanego rekordu bazy danych
string dane[3];
for (int i=0; i<3; i++)
{
string::size_type tmppos = e.find("*", pos+1);
if (tmppos == string::npos && i<2)
{
// po ostatniej kolumnie nie musi być "*"
cout << "Dane w bazie w nieprawidłowym formacie (przetwarzany rekord: "" << buf << "")" << endl;
break;
}
dane[i] = e.substr(pos+1, tmppos-pos-1);
pos = tmppos;
}
// drabinka cout wyswietlająca zawartość znalezionego rekordu bazy damych
cout << "Znaleziono rekord pasujący do parametru wyszukiwania:<br>n";
cout << "<table>";
cout << "<tr><td><b>Nazwa uzytkownika:</b></td><td><i>" << query << "</i></td></tr>" << endl;
cout << "<tr><td><b>Miasto:</b></td><td><i>" << dane[0] << "</i></td></tr>" << endl;
cout << "<tr><td><b>Telefon:</b></td><td><i>" << dane[1] << "</i></td></tr>" << endl;
cout << "<tr><td><b>Wiek:</b></td><td><i>" << dane[2] << "</i></td></tr>" << endl;
cout << "</table>" << endl;
znaleziony = 1;
}
}
}
while (!plik.eof());
plik.close();
// gdy nie znaleziono oosoby odpowiadającej parametrowi wyszukiwania
if (!znaleziony)
{
cout << "Szukana osoba " << query << " nie została znaleziona w bazie" << endl;
}
}
// zamknięcie znaczników dokumentu
cout << foot;
}
Z góry dziękuję za wszelką okazaną pomoc.
Paweł