Link hữu ích về C++
Tutorialspoint − Loạt bài hướng dẫn của chúng tôi xây dựng dựa trên nguồn này.
C++ Programming Language Tutorials − Loạt bài hướng dẫn về Ngôn ngữ lập trình C++
C++ Programming − Sách này về C++ và tính tương tác của nó với thiết kế phần mềm và
sự sử dụng ngôn ngữ C++ trong cuộc sống thực.
C++ FAQ − Câu hỏi thường xuyên về C++
Free Country − Cung cấp source code về C++ miễn phí và thư viện C++ cho một số
chương trình như lập trình game, thư viện Template chuẩn và lập trình GUI.
200 trang |
Chia sẻ: truongthinh92 | Lượt xem: 2564 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Tài liệu Lập trình C++, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
#include
#include
#include
#include
using namespace std;
template
class Stack {
private:
vector elems; // elements
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 151
public:
void push(T const&); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const{ // return true if empty.
return elems.empty();
}
};
template
void Stack::push (T const& elem)
{
// append copy of passed element
elems.push_back(elem);
}
template
void Stack::pop ()
{
if (elems.empty()) {
throw out_of_range("Stack::pop(): empty stack");
}
// remove last element
elems.pop_back();
}
template
T Stack::top () const
{
if (elems.empty()) {
throw out_of_range("Stack::top(): empty stack");
}
// return copy of last element
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 152
return elems.back();
}
int main()
{
try {
Stack intStack; // stack of ints
Stack stringStack; // stack of strings
// manipulate int stack
intStack.push(7);
cout << intStack.top() <<endl;
// manipulate string stack
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
Biên dịch và chạy code trên sẽ cho kết quả:
7
hello
Exception: Stack::pop(): empty stack
Bộ tiền xử lý (Preprocessor) trong C++
Bộ tiền xử lý (Preprocessor) là các directive (chỉ thị), cung cấp chỉ lệnh tới bộ biên dịch để tiền xử
lý thông tin trước khi bắt đầu biên dịch thực sự.
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 153
Tất cả chỉ thị tiền xử lý (Preprocessor directive) bắt đầu với #, và chỉ có các ký tự khoảng trống
trắng (white-space) là có thể xuất hiện ở trước một chỉ thị tiền xử lý trên một dòng. Chỉ thị tiền xử lý
không là các lệnh trong C++, vì thế chúng không kết thúc với một dấu chấm phảy.
Bạn đã thấy một chỉ thị tiền xử lý là #include trong tất cả ví dụ. Macro này được sử dụng để bao
một Header file vào trong source file.
Có một số chỉ thị tiền xử lý được hỗ trợ bởi C++ như #include, #define, #if, #else, #line, Dưới
đây, chúng tôi sẽ trình bày các chỉ thị tiền xử lý quan trọng trong C++:
Bộ tiền xử lý # define trong C++
Chỉ thị tiền xử lý #define tạo các biểu tượng hằng. Biểu tượng hằng là một macro và mẫu chung
của chỉ thị tiền xử lý này trong C++ là:
#define macro-name replacement-text
Khi dòng này xuất hiện trong một file, tất cả macro xuất hiện theo sau trong file này sẽ được thay
thế bởi replacement-text trước khi chương trình được biên dịch. Ví dụ:
#include
using namespace std;
#define PI 3.14159
int main ()
{
cout << "Value of PI :" << PI << endl;
return 0;
}
Giả sử chúng ta có source file, sau đó biên dịch nó với tùy chọn –E và hướng kết quả tới test.p.
Bây giờ, nếu bạn kiểm tra test.p, nó sẽ có nhiều thông tin và tại dưới cùng, bạn sẽ tinh chỉnh giá trị
được thay thế như sau:
$gcc -E test.cpp > test.p
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 154
...
int main ()
{
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
Function-Like Macro trong C++
Bạn có thể sử dụng chỉ thị tiền xử lý #define trong C++ để định nghĩa một macro mà sẽ nhận tham
số như sau:
#include
using namespace std;
#define MIN(a,b) (((a)<(b)) ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
cout <<"The minimum is " << MIN(i, j) << endl;
return 0;
}
Biên dịch và thực thi code trên sẽ cho kết quả sau:
The minimum is 30
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 155
Biên dịch có điều kiện trong C++
Có một số chỉ thị tiền xử lý có thể sử dụng để biên dịch có sự tuyển chọn giữa các phần trong
source code của bạn. Tiến trình này được gọi là biên dịch có điều kiện.
Chỉ lệnh tiền xử lý có điều kiện khá giống với cấu trúc lựa chọn if. Bạn xét code sau:
#ifndef NULL
#define NULL 0
#endif
Bạn có thể biên dịch một chương trình với mục đích debug và có thể tắt hoặc bật việc debug này
bởi sử dụng một macro trong C++, như sau:
#ifdef DEBUG
cerr <<"Variable x = " << x << endl;
#endif
Lệnh cerr để được biên dịch trong chương trình nếu biểu tượng hằng DEBUG đã được định nghĩa
ở trước chỉ thị #ifdef DEBUG. Bạn có thể sử dụng lệnh #if 0 để chú thích một phần của chương
trình, như sau:
#if 0
code prevented from compiling
#endif
Bạn thử ví dụ sau:
#include
using namespace std;
#define DEBUG
#define MIN(a,b) (((a)<(b)) ? a : b)
int main ()
{
int i, j;
i = 100;
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 156
j = 30;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif
#if 0
/* This is commented part */
cout << MKSTR(HELLO C++) << endl;
#endif
cout <<"The minimum is " << MIN(i, j) << endl;
#ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;
#endif
return 0;
}
Biên dịch và thực thi code trên sẽ cho kết quả sau:
Trace: Inside main function
The minimum is 30
Trace: Coming out of main function
Các toán tử # và ## trong C++
Các toán tử tiền xử lý # và ## là có sẵn trong C++ và ANSI/ISO C. Toán tử # thông báo rằng đoạn
văn bản thay thế sẽ được chuyển đổi sang một chuỗi bao quanh bởi dấu ngoặc kép.
Bạn xét định nghĩa macro sau:
#include
using namespace std;
#define MKSTR( x ) #x
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 157
int main ()
{
cout << MKSTR(HELLO C++) << endl;
return 0;
}
Biên dịch và chạy code trên sẽ cho kết quả sau:
HELLO C++
Bây giờ, chúng ta xét cách nó đã làm việc. Nó là đơn giản để hiểu rằng bộ tiền xử lý C++ chuyển
dòng sau:
cout << MKSTR(HELLO C++) << endl;
Thành dòng:
cout << "HELLO C++" << endl;
Toán tử ## được sử dụng để nối chuỗi hai token. Ví dụ:
#define CONCAT( x, y ) x ## y
Khi CONCAT xuất hiện trong chương trình, các tham số của nó được nối chuỗi và được sử dụng
để thay thế cho macro. Ví dụ, CONCAT(HELLO, C++) được thay thế bởi "HELLO C++" trong
chương trình sau:
#include
using namespace std;
#define concat(a, b) a ## b
int main()
{
int xy = 100;
cout << concat(x, y);
return 0;
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 158
}
Biên dịch và thực thi code trên sẽ cho kết quả:
100
Giờ chúng ta xét cách chúng đã làm việc. Đơn giản là bộ tiền xử lý C++ chuyển dòng sau:
cout << concat(x, y);
Thành dòng:
cout << xy;
Macro tiền định nghĩa trong C++
C++ cung cấp một số macro được định nghĩa trước như liệt kê dưới đây:
Macro Miêu tả
__LINE__ Chứa số dòng hiện tại của chương trình khi nó đang được biên
dịch
__FILE__ Chứa tên file hiện tại của chương trình khi nó đang được biên
dịch
__DATE__ Chứa một chuỗi month/day/year là ngày source code được biên
dịch
__TIME__ Chứa một chuỗi hour:minute:second là thời gian chương trình
được biên dịch
Dưới đây là ví dụ cho tất cả macro ở trên trong C++:
#include
using namespace std;
int main ()
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 159
{
cout << "Value of __LINE__ : " << __LINE__ << endl;
cout << "Value of __FILE__ : " << __FILE__ << endl;
cout << "Value of __DATE__ : " << __DATE__ << endl;
cout << "Value of __TIME__ : " << __TIME__ << endl;
return 0;
}
Biên dịch và thực thi code trên sẽ cho kết quả:
Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48
Xử lý tín hiệu (Signal Handling) trong C++
Tín hiệu (Signal) là các ngắt (interrupt) được phân phối tới một tiến trình xử lý bởi hệ điều hành
mà có thể kết thúc một chương trình. Bạn có thể tạo các ngắt bằng việc nhấn CTRL+C trên hệ
thống UNIX, LINUX, Mac OS hoặc Windows.
Có các signal mà không thể bị bắt bởi chương trình, nhưng cũng có signal mà bạn có thể bắt trong
chương trình của bạn, và có thể thực hiện các hành động thích hợp dựa trên signal đó. Những
signal này được định nghĩa trong Header file của C++ là .
Signal Miêu tả
SIGABRT Sự kết thúc bất thường của chương trình, ví dụ một lời gọi tới abort
SIGFPE Một hoạt động số học không đúng, ví dụ như chia cho số 0 hoặc một hoạt
động làm tràn luồng (overflow)
SIGILL Sự phát hiện một chỉ lệnh không hợp lệ
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 160
SIGINT Nhận một tín hiệu tương tác
SIGSEGV Một truy cập không hợp lệ tới storage
SIGTERM Một yêu cầu kết thúc được gửi tới chương trình
Hàm signal() trong C++
Thư viện xử lý tín hiệu trong C++ cung cấp hàm signal để bẫy các sự kiện không được mong đợi.
Dưới đây là cú pháp của hàm signal() trong C++:
void (*signal (int sig, void (*func)(int)))(int);
Hàm này nhận hai tham số: tham số đầu tiên là một integer mà biểu diễn số hiệu tín hiệu (signal
number) và tham số thứ hai là một con trỏ tới hàm xử lý tín hiệu.
Bây giờ, viết một chương trình C++ đơn giản để bắt tín hiệu SIGINT bởi sử dụng
hàmsignal() trong C++. Bất cứ tín hiệu nào bạn muốn bắt trong chương trình, bạn phải ghi tín hiệu
đó bởi sử dụng hàm signal và liên kết nó với một Signal Handler. Bạn xét ví dụ:
#include
#include
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// cleanup and close up stuff here
// terminate program
exit(signum);
}
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 161
int main ()
{
// register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
while(1){
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
Khi code trên được biên dịch và thực thi, nó cho kết quả sau:
Going to sleep....
Going to sleep....
Going to sleep....
Bây giờ, nhấn CTRL+C để ngắt chương trình và bạn sẽ thấy rằng chương trình sẽ bắt tín hiệu này
và sẽ in cái gì đó như sau:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
Hàm raise() trong C++
Bạn có thể tạo các tín hiệu bởi hàm raise() trong C++, mà nhận một số integer biểu diễn signal
number như một tham số và có cú pháp như sau:
int raise (signal sig);
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 162
Ở đây, sig là signal number để gửi bất kỳ loại tín hiệu nào: SIGINT, SIGABRT, SIGFPE, SIGILL,
SIGSEGV, SIGTERM, SIGHUP. Dưới đây là ví dụ tạo một tín hiệu nội tại bởi sử dụng hàm raise()
trong C++, như sau:
#include
#include
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// cleanup and close up stuff here
// terminate program
exit(signum);
}
int main ()
{
int i = 0;
// register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
while(++i){
cout << "Going to sleep...." << endl;
if( i == 3 ){
raise( SIGINT);
}
sleep(1);
}
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 163
return 0;
}
Biên dịch và thực thi code trên, nó sẽ cho kết quả sau:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
Đa luồng (Multithread) trong C++
Đa luồng (Multithreading) là một form chuyên dụng của đa nhiệm (multitasking) và một đa nhiệm
là tính năng cho phép máy tính của bạn chạy hai hoặc nhiều chương trình đồng thời. Nói chung, có
hai kiểu đa nhiệm là: process-based và thread-based tương ứng: dựa trên tiến trình và dựa trên
luồng.
Đa nhiệm dựa trên tiến trình xử lý việc thực thi đồng thời của các chương trình. Đa nhiệm dựa trên
luồng xử lý việc thực thi đồng thời các phần của cùng một chương trình.
Một chương trình đa luồng chứa hai hoặc nhiều phần mà có thể chạy đồng thời. Mỗi phần của
chương trình đó được gọi là một thread, và mỗi thread định nghĩa một path riêng biệt của sự thực
thi.
C++ không chứa bất kỳ hỗ trợ có sẵn nào cho các ứng dụng đa luồng. Thay vào đó, nó dựa hoàn
toàn vào Hệ điều hành để cung cấp tính năng này.
Chương này giả sử bạn đang làm việc trên Hệ điều hành Linux và chúng tôi đang chuẩn bị viết
chương trình đa luồng trong C++ bởi sử dụng POSIX. POSIX Threads hoặc Pthreads cung cấp
API mà có sẵn trên nhiều hệ thống như FreeBSD, NetBSD, GNU/Linux, Mac OS X và Solaris.
Tạo Thread trong C++
Đây là chương trình chúng ta sử dụng để tạo một POSIX thread:
#include
pthread_create (thread, attr, start_routine, arg)
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 164
Ở đây, pthread_create tạo một thread mới và làm nó có thể thực thi. Chương trình này có thể
được gọi bất cứ thời điểm nào ở bất cứ đâu trong code của bạn. Dưới đây là miêu tả các tham số:
Tham số Miêu tả
thread Một định danh duy nhất cho thread mới được trả về bởi chương trình
con
attr Một thuộc tính mà có thể được sử dụng để thiết lập các thuộc tính của
thread. Bạn có thể xác định một đối tượng thuộc tính thread, hoặc
NULL cho các giá trị mặc định
start_routine Chương trình C++ mà thread này sẽ thực thi một khi nó được tạo
arg Một tham số đơn mà có thể được truyền tới start_routine. Nó phải
được truyền bởi tham chiếu dạng một con trỏ của kiểu void. NULL có
thể được sử dụng nếu không có tham số nào được truyền
Số thread tối đa có thể được tạo bởi một tiến trình là phụ thuộc vào trình triển khai
(Implementation). Một khi được tạo, các thread là ngang hàng, và có thể tạo các thread khác.
Không có sự phụ thuộc giữa các thread trong C++.
Kết thuốc Thread trong C++
Chương trình sau được sử dụng để kết thúc một POSIX thread trong C++:
#include
pthread_exit (status)
Ở đây pthread_exit được sử dụng để kết thúc một thread. Chương trình pthread_exit() được gọi
sau khi một thread đã hoàn thành công việc của nó và không cần thiết phải tồn tại nữa.
Nếu main() kết thúc trước các thread nó đã tạo, và kết thúc chương trình pthread_create(), thì các
thread khác sẽ tiếp tục thực thi. Nếu không thì, chúng sẽ tự động được kết thúc khi main() hoàn
thành.
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 165
Ví dụ
Ví dụ đơn giản sau tạo 5 thread với chương trình pthread_create(). Mỗi thread in một thông báo
“Hello World!”, và sau đó kết thúc với một lời gọi tới pthread_exit() trong C++:
#include
#include
#include
using namespace std;
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
cout << "Hello World! Thread ID, " << tid << endl;
pthread_exit(NULL);
}
int main ()
{
pthread_t threads[NUM_THREADS];
int rc;
int i;
for( i=0; i < NUM_THREADS; i++ ){
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], NULL,
PrintHello, (void *)i);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 166
}
pthread_exit(NULL);
}
Biên dịch chương trình trên sử dụng thư viện –lpthread như sau:
$gcc test.cpp -lpthread
Bây giờ, thực thi chương trình sẽ cho kết quả:
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Hello World! Thread ID, 0
Hello World! Thread ID, 1
Hello World! Thread ID, 2
Hello World! Thread ID, 3
Hello World! Thread ID, 4
Truyền tham số tới Thread trong C++
Ví dụ này minh họa cách truyền nhiều tham số thông qua một cấu trúc. Bạn có thể truyền bất kỳ
kiểu dữ liệu nào trong một Thread callback, bởi vì nó trỏ tới void như được giải thích trong ví dụ
sau:
#include
#include
#include
using namespace std;
#define NUM_THREADS 5
struct thread_data{
int thread_id;
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 167
char *message;
};
void *PrintHello(void *threadarg)
{
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
cout thread_id ;
cout message << endl;
pthread_exit(NULL);
}
int main ()
{
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc;
int i;
for( i=0; i < NUM_THREADS; i++ ){
cout <<"main() : creating thread, " << i << endl;
td[i].thread_id = i;
td[i].message = "This is message";
rc = pthread_create(&threads[i], NULL,
PrintHello, (void *)&td[i]);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 168
pthread_exit(NULL);
}
Khi code trên được biên dịch và thực thi, nó cho kết quả sau:
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Thread ID : 3 Message : This is message
Thread ID : 2 Message : This is message
Thread ID : 0 Message : This is message
Thread ID : 1 Message : This is message
Thread ID : 4 Message : This is message
Kết hợp và Tháo gỡ các Thread trong C++
Hai cú pháp sau được sử dụng để kết hợp (joining) hoặc tháo gỡ (detaching) các Thread trong
C++:
pthread_join (threadid, status)
pthread_detach (threadid)
Chương trình con pthread_join() đóng khối thread đang gọi tới khi threadid kết thúc. Khi một thread
được tạo, một trong các thuộc tính định nghĩa nó là joinable hoặc detached. Chỉ các thread được
tạo với dạng joinable có thể được kết hợp. Nếu một thread được tạo với dạng detached, nó không
bao giờ được kết hợp.
Ví dụ sau minh họa cách đợi cho các thread kết thúc bởi sử dụng chương trình kết hợp Pthread
trong C++:
#include
#include
#include
#include
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 169
using namespace std;
#define NUM_THREADS 5
void *wait(void *t)
{
int i;
long tid;
tid = (long)t;
sleep(1);
cout << "Sleeping in thread " << endl;
cout << "Thread with id : " << tid << " ...exiting " << endl;
pthread_exit(NULL);
}
int main ()
{
int rc;
int i;
pthread_t threads[NUM_THREADS];
pthread_attr_t attr;
void *status;
// Initialize and set thread joinable
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for( i=0; i < NUM_THREADS; i++ ){
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], NULL, wait, (void *)i );
if (rc){
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 170
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
// free attribute and wait for the other threads
pthread_attr_destroy(&attr);
for( i=0; i < NUM_THREADS; i++ ){
rc = pthread_join(threads[i], &status);
if (rc){
cout << "Error:unable to join," << rc << endl;
exit(-1);
}
cout << "Main: completed thread id :" << i ;
cout << " exiting with status :" << status << endl;
}
cout << "Main: program exiting." << endl;
pthread_exit(NULL);
}
Khi code trên được biên dịch và thực thi, nó cho kết quả sau:
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Sleeping in thread
Thread with id : 0 .... exiting
Sleeping in thread
Thread with id : 1 .... exiting
Sleeping in thread
Thread with id : 2 .... exiting
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 171
Sleeping in thread
Thread with id : 3 .... exiting
Sleeping in thread
Thread with id : 4 .... exiting
Main: completed thread id :0 exiting with status :0
Main: completed thread id :1 exiting with status :0
Main: completed thread id :2 exiting with status :0
Main: completed thread id :3 exiting with status :0
Main: completed thread id :4 exiting with status :0
Main: program exiting.
Lập trình Web trong C++
CGI là gì?
Common Gateway Interface hoặc CGI là một tập hợp các chuẩn mà định nghĩa cách thông
tin được trao đổi giữa Web Server và một Custom Script.
CGI Specification hiện tại được duy trì bởi NCSA và NCSA định nghĩa CGI như sau:
Common Gateway Interface hoặc CGI là một chuẩn cho các chương trình kết nối dị mạng
ngoại vi (external gateway programs) tới Interface với thông tin từ Server như HTTP
Server.
Phiên bản hiện tại là CGI/1.1 và CGI/1.2 đang trong quá trình phát triển.
Web Browsing
Để hiểu khái niệm về CGI, chúng ta xem những gì xảy ra khi chúng ta nhấn vào một hyperlink để
tới một Webpage hoặc URL cụ thể.
Trình duyệt của bạn liên hệ HTTP Web Server và yêu cầu một URL, ví dụ: filename.
Web Server sẽ parse URL đó và sẽ tìm kiếm filename. Nếu nó tìm thấy file đã yêu cầu, thì
Web Server gửi file đó trở lại trình duyệt, nếu không thì, nó gửi một thông báo lỗi chỉ rằng
bạn đã yêu cầu một wrong file.
Trình duyệt Web nhận phản hồi từ Web Server và hiển thị file đã nhận được hoặc thông báo
lỗi dựa trên phản hồi đã nhận.
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 172
Tuy nhiên, nó là có thể để thiết lập HTTP Server theo cách mà bất cứ khi nào một file trong một thư
mục cụ thể được yêu cầu, thì file đó không được gửi trở lại; thay cho việc nó được thực thi như là
một chương trình và output được tạo từ chương trình đã gửi tới trình duyệt để hiển thị.
Common Gateway Interface hoặc CGI là một giao thức chuẩn cho các ứng dụng (được gọi là CGI
program hoặc CGI script) khả năng tương tác với Web Server và với Client. Những CGI program
này có thể được viết bằng Python, PERL, Shell, C hoặc C++
Sơ đồ cấu trúc CGI
Dưới đây là sơ đồ một cấu trúc đơn giản của CGI:
Cấu hình Web Server
Trước khi bạn tiếp tục với lập trình CGI, đảm bảo rằng Web Server của bạn hỗ trợ CGI và nó được
định cấu hình để xử lý CGI Program. Tất cả CGI program để được thực thi bởi HTTP Server được
giữ trong một thư mục được định cấu hình trước. Thư mục này được gọi là CGI directory, và theo
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 173
qui ước, nó được đặt tên là /var/www/cgi-bin. Theo qui ước, CGI file có đuôi là .cgi, vì thế chúng là
có thể thực thi trong C++.
Theo mặc định, Apache Web Server được định cấu hình để chạy CGI Program trong /var/www/cgi-
bin. Nếu bạn muốn xác định bất kỳ thư mục khác để chạy CGI script của bạn, thì bạn phải sửa đổi
khu vực sau trong httpd.conf file:
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
Options All
Chương trình CGI đầu tiên
Xét nội dung chương trình C++ sau:
#include
using namespace std;
int main ()
{
cout << "Content-type:text/html\r\n\r\n";
cout \n";
cout \n";
cout Hello World - First CGI Program\n";
cout \n";
cout \n";
cout Hello World! This is my first CGI program\n";
cout \n";
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 174
cout \n";
return 0;
}
Biên dịch code trên và đặt tên là cplusplus.cgi. File này được giữ trong thư mục /var/www/cgi-bin
và nó có nội dung như sau. Trước khi chạy CGI Program của bạn, bảo đảm rằng bạn đã chuyển
chế độ của file bởi sử dụng lệnh chmod 755 cplusplus.cgi trên UNIX để làm file có thể thực thi. Bây
giờ, nếu bạn nhấn vào cplusplus.cgi, thì nó sẽ cho kết quả:
Hello World! This is my first CGI program
Chương trình C++ trên là một chương trình đơn giản mà đang viết output trên STDOUT file, ví dụ:
màn hình. Có một tính năng quan trọng có sẵn để dòng đầu tiên được in là Content-
type:text/html\r\n\r\n. Dòng này gửi trở lại trình duyệt và xác định kiểu nội dung để được hiển thị
trên màn hình trình duyệt. Bây giờ bạn đã hiểu khái niệm cơ bản về CGI và bạn có thể viết nhiều
CGI Program phức tạp bởi sử dụng C++. Một CGI Program trong C++ có thể tương tác với bất kỳ
hệ thống ngoại vi khác như RDBMS, để trao đổi thông tin.
HTTP Header
Dòng Content-type:text/html\r\n\r\n là một phần của HTTP Header, mà được gửi tới trình duyệt.
Tất cả HTTP Header có form sau:
HTTP Field Name: Field Content
For Example
Content-type: text/html\r\n\r\n
Dưới đây là một số HTTP Header quan trọng, mà bạn sẽ sử dụng thường xuyên trong Lập trình
CGI.
Header Miêu tả
Content-type: Một chuỗi MIME định nghĩa định dạng của file đang được trả về.
Ví dụ: Content-type:text/html
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 175
Expires: Date Ngày thông tin hết hiệu lực. Nó nên được sử dụng bởi trình
duyệt để quyết định khi nào một trang cần được refresh. Một
chuỗi date hợp lệ nên trong định dạng 01 Jan 1998 12:00:00
GMT
Location: URL URL mà nên được trả về thay cho URL đã yêu cầu. Bạn có thể
sử dụng trường này để redirect một yêu cầu tới bất kỳ file nào
Last-modified: Date Ngày sửa đổi cuối cùng của nguồn
Content-length: N Độ dài, bằng byte, của dữ liệu đang được trả về. Trình duyệt sử
dụng giá trị này để báo cáo lượng thời gian download ước lượng
cho một file
Set-Cookie: String Thiết lập cookie đã truyền thông qua string
Biến môi trường của CGI
Tất cả CGI Program sẽ có truy cập tới các biến môi trường sau đây. Những biến này đóng vai trò
quan trọng trong khi viết bất kỳ CGI Program nào:
Tên biến Miêu tả
CONTENT_TYPE Kiểu dữ liệu của nội dung. Được sử dụng khi Client gửi nội dung
đính kèm tới Server. Ví dụ: file upload
CONTENT_LENGTH Độ dài của thông tin truy vấn. Nó chỉ có sẵn cho các yêu cầu
POST
HTTP_COOKIE Trả về các cookie đã thiết lập trong form là cặp key/value
HTTP_USER_AGENT Trường request-header là User-Agent chứa thông tin về User
Agent bắt đầu yêu cầu đó. Nó là tên của trình duyệt web
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 176
PATH_INFO Là path cho CGI script
QUERY_STRING Thông tin mã hóa URL được gửi với phương thức GET
REMOTE_ADDR Địa chỉ IP của host từ xa tạo yêu cầu đó. Nó có thể là hữu ích
cho mục đích log hoặc authentication
REMOTE_HOST Tên đầy đủ của host tạo yêu cầu đó. Nếu thông tin này không có
sẵn, thì REMOTE_ADDR có thể được sử dụng để lấy địa chỉ IP
REQUEST_METHOD Phương thức được sử dụng để tạo yêu cầu. Các phương thức
phổ biến là GET và POST
SCRIPT_FILENAME Path đầy đủ tới CGI script
SCRIPT_NAME Tên của CGI script
SERVER_NAME Hostname hoặc địa chỉ IP của Server
SERVER_SOFTWARE Tên và phiên bản của phần mềm mà Server đang chạy
Sau đây là chương trình CGI nhỏ để liệt kê tất cả biến CGI. Bạn click vào đây để xem kết quả:Get
Environment
#include
#include
using namespace std;
const string ENV[ 24 ] = {
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 177
"COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",
"HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING",
"HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION",
"HTTP_HOST", "HTTP_USER_AGENT", "PATH",
"QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
"REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME",
"SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN",
"SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL",
"SERVER_SIGNATURE","SERVER_SOFTWARE" };
int main ()
{
cout << "Content-type:text/html\r\n\r\n";
cout \n";
cout \n";
cout CGI Envrionment Variables\n";
cout \n";
cout \n";
cout ";
for ( int i = 0; i < 24; i++ )
{
cout " ";
// attempt to retrieve value of environment variable
char *value = getenv( ENV[ i ].c_str() );
if ( value != 0 ){
cout << value;
}else{
cout << "Environment variable does not exist.";
}
cout \n";
}
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 178
cout <\n";
cout \n";
cout \n";
return 0;
}
Thư viện CGI trong C++
Với các ví dụ thực tế, bạn sẽ cần thực hiện nhiều hoạt động bởi CGI Program của bạn. Có một thư
viện CGI được viết cho chương trình C++, mà bạn có thể tải về từ:ftp://ftp.gnu.org/gnu/cgicc/ và
theo các bước sau để cài đặt thư viện này:
$tar xzf cgicc-X.X.X.tar.gz
$cd cgicc-X.X.X/
$./configure --prefix=/usr
$make
$make install
Bạn có thể kiểm tra Documentation có sẵn tại: C++ CGI Lib Documentation.
Phương thức POST và GET
Bạn gặp một số tình huống khi bạn cần truyền một số thông tin từ trình duyệt tới Web Server và
sau cùng tới CGI Program của bạn. Hai phương thức được sử dụng thường xuyên nhất bởi trình
duyệt để truyền các thông tin này tới Web Server là Phương thức GET và Phương thức POST.
Truyền thông tin bởi sử dụng phương thức GET
Phương thức GET gửi thông tin người dùng đã mã hóa được phụ thêm tới trang yêu cầu. Trang và
thông tin đã mã hóa được phân biệt bởi ký tự ? như sau:
Phương thức GET là phương thức mặc định để truyền thông tin từ trình duyệt tới Web Server và
nó tạo ra một chuỗi dài xuất hiện trong Location:box của trình duyệt. Đừng bao giờ sử dụng
phương thức GET nến bạn có mật khẩu hoặc thông tin nhạy cảm khác để truyền tới Server.
Phương thức GET có giới hạn kích cỡ và bạn có thể truyền 1024 ký tự trong một Request String.
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 179
Khi sử dụng phương thức GET, thông tin được truyền bởi trường HTTP Header là
QUERY_STRING và sẽ là có thể truy cập trong CGI Program thông qua biến môi trường
QUERY_STRING.
Bạn có thể truyền thông tin bằng việc nối chuỗi các cặp key/value cùng với bất kỳ URL hoặc bạn có
thể sử dụng các thẻ HTML để truyền thông tin bởi sử dụng phương thức GET.
Ví dụ URL đơn giản sử dụng phương thức GET
Đây là một URL đơn giản sẽ truyền hai value tới chương trình hello_get.py bởi sử dụng phương
thức GET.
/cgi-bin/cpp_get.cgi?first_name=ZARA&last_name=ALI
Dưới đây là chương trình để tạo CGI Program là cpp_get.cgi để xử lý input được cung cấp bởi
trình duyệt web. Chúng ta đang sử dụng thư viện CGI trong C++, để làm cho nó dễ dàng hơn để
truy cập thông tin đã truyền:
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cgicc;
int main ()
{
Cgicc formData;
cout << "Content-type:text/html\r\n\r\n";
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 180
cout \n";
cout \n";
cout Using GET and POST Methods\n";
cout \n";
cout \n";
form_iterator fi = formData.getElement("first_name");
if( !fi->isEmpty() && fi != (*formData).end()) {
cout << "First name: " << **fi << endl;
}else{
cout << "No text entered for first name" << endl;
}
cout \n";
fi = formData.getElement("last_name");
if( !fi->isEmpty() &&fi != (*formData).end()) {
cout << "Last name: " << **fi << endl;
}else{
cout << "No text entered for last name" << endl;
}
cout \n";
cout \n";
cout \n";
return 0;
}
Bây giờ, biên dịch chương trình trên như sau:
$g++ -o cpp_get.cgi cpp_get.cpp -lcgicc
Tạo cpp_get.cgi và đặt nó trong thư mục CGI của bạn.
Nó sẽ cho kết quả:
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 181
First name: ZARA
Last name: ALI
Ví dụ về FORM bởi sử dụng phương thức GET
Ví dụ đơn giản sau sẽ truyền hai value bởi sử dụng HTML FORM và nút submit. Chúng ta đang sử
dụng cùng CGI Program là cpp_get.cgi để xử lý input này.
First Name:
Last Name:
Đây là output thực sự của form trên. Bạn có thể nhập First và Last Name và sau đó click nút
Submit để xem kết quả:
First Name:
Last Name:
Submit
Truyền thông tin bởi sử dụng phương thức POST
Một phương thức chung đáng tin cậy hơn để truyền thông tin tới một CGI Program là phương thức
POST. Nó đóng gói thông tin theo cách giống phương thức GET, nhưng thay vì gửi nó ở dạng một
chuỗi văn bản sau một dấu ? trong URL, nó gửi ở dạng một thông báo riêng biệt. Thông báo này
tới CGI Script trong form đầu vào chuẩn.
Cùng sử dụng CGI Program là cpp_get.cgi để xử lý phương thức POST. Chúng ta sử dụng cùng ví
dụ như trên, mà sẽ truyền hai value bởi sử dụng HTML FORM và nút Submit, nhưng lần này với
phương thức POST như sau:
First Name:
Last Name:
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 182
Đây là output thực sự của form trên. Bạn nhập First và Last Name và sau đó nhấn nút Submit để
xem kết quả:
First Name:
Last Name:
Submit
Truyền Checkbox Data tới CGI Program
Checkbox được sử dụng khi có nhiều hơn một tùy chọn là cần thiết để được lựa chọn:
HTML code sau là ví dụ cho một form với hai checkbox:
<form action="/cgi-bin/cpp_checkbox.cgi"
method="POST"
target="_blank">
Maths
Physics
Kết quả của code này là form sau:
Maths Physics
Select Subject
Chương trình C++ sau sẽ tạo cpp_checkbox.cgi để xử lý input được cung cấp bởi trình duyệt
thông qua nút checkbox:
#include
#include
#include
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 183
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cgicc;
int main ()
{
Cgicc formData;
bool maths_flag, physics_flag;
cout << "Content-type:text/html\r\n\r\n";
cout \n";
cout \n";
cout Checkbox Data to CGI\n";
cout \n";
cout \n";
maths_flag = formData.queryCheckbox("maths");
if( maths_flag ) {
cout << "Maths Flag: ON " << endl;
}else{
cout << "Maths Flag: OFF " << endl;
}
cout \n";
physics_flag = formData.queryCheckbox("physics");
if( physics_flag ) {
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 184
cout << "Physics Flag: ON " << endl;
}else{
cout << "Physics Flag: OFF " << endl;
}
cout \n";
cout \n";
cout \n";
return 0;
}
Truyền Radiobutton Data tới CGI Program
Radio Button được sử dụng khi chỉ có một tùy chọn là cần thiết để lựa chọn.
HTML code sau là ví dụ cho form với hai radio button:
<form action="/cgi-bin/cpp_radiobutton.cgi"
method="post"
target="_blank">
<input type="radio" name="subject" value="maths"
checked="checked"/> Maths
Physics
Kết quả của code trên là form sau:
Maths Physics
Select Subject
Chương trình C++ sau sẽ tạo cpp_radiobutton.cgi để xử lý input được cung cấp bởi trình duyệt
web thông qua các radio button:
#include
#include
#include
#include
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 185
#include
#include
#include
#include
#include
using namespace std;
using namespace cgicc;
int main ()
{
Cgicc formData;
cout << "Content-type:text/html\r\n\r\n";
cout \n";
cout \n";
cout Radio Button Data to CGI\n";
cout \n";
cout \n";
form_iterator fi = formData.getElement("subject");
if( !fi->isEmpty() && fi != (*formData).end()) {
cout << "Radio box selected: " << **fi << endl;
}
cout \n";
cout \n";
cout \n";
return 0;
}
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 186
Truyền Text Area Data tới CGI Program
Phần tử TEXTAREA được sử dụng khi văn bản nhiều dòng phải được truyền tới CGI Program.
HTML code sau là ví dụ cho một form với một TEXTAREA box:
<form action="/cgi-bin/cpp_textarea.cgi"
method="post"
target="_blank">
Type your text here...
Đây là kết quả của form trên:
Submit
Chương trình C++ sau sẽ tạo cpp_textarea.cgi để xử lý input được cung cấp bởi trình duyệt web
thông qua text area:
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 187
using namespace cgicc;
int main ()
{
Cgicc formData;
cout << "Content-type:text/html\r\n\r\n";
cout \n";
cout \n";
cout Text Area Data to CGI\n";
cout \n";
cout \n";
form_iterator fi = formData.getElement("textcontent");
if( !fi->isEmpty() && fi != (*formData).end()) {
cout << "Text Content: " << **fi << endl;
}else{
cout << "No text entered" << endl;
}
cout \n";
cout \n";
cout \n";
return 0;
}
Truyền DropDown Box Data tới CGI Program
DropDown Box được sử dụng khi có nhiều tùy chọn có sẵn, nhưng chỉ có một hoặc hai sẽ được
chọn:
HTML code sau là ví dụ cho một form với một Dropdown box:
<form action="/cgi-bin/cpp_dropdown.cgi"
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 188
method="post" target="_blank">
Maths
Physics
Kết quả của code trên là form sau:
Maths
Submit
Chương trình C++ sau sẽ tạo cpp_dropdown.cgi để xử lý input được cung cấp bởi trình duyệt
web thông qua dropdown box:
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cgicc;
int main ()
{
Cgicc formData;
cout << "Content-type:text/html\r\n\r\n";
cout \n";
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 189
cout \n";
cout Drop Down Box Data to CGI\n";
cout \n";
cout \n";
form_iterator fi = formData.getElement("dropdown");
if( !fi->isEmpty() && fi != (*formData).end()) {
cout << "Value Selected: " << **fi << endl;
}
cout \n";
cout \n";
cout \n";
return 0;
}
Sử dụng Cookie trong CGI
HTTP Protocol là một giao thức Stateless. Nhưng với một Website thương mại, nó là cần thiết để
duy trình thông tin session giữa các trang khác nhau. Ví dụ, một tiến trình đăng ký của người sử
dụng có thể kết thúc sau khi hoàn thành qua nhiều trang. Nhưng cách để duy trì thông tin session
của người dùng khi họ duyệt qua nhiều trang là như thế nào.
Trong nhiều tình huống, sử dụng Cookie là phương thức hiệu quả nhất để ghi nhớ và theo dấu việc
đặt hàng, mua hàng, hàng hóa ưa thích,
Cách nó làm việc
Server của bạn gửi một số dữ liệu tới trình duyệt khách truy cập trong form của một Cookie. Trình
duyệt có thể chấp nhận Cookie này. Nếu nó chấp nhận, nó được lưu giữ ở dạng một bản ghi thuần
văn bản trên Hard drive của khách truy cập. Bây giờ, khi khác truy cập tới trang khác trên site của
bạn, Cookie này là có sẵn để thu hồi. Khi được thu hồi, Server của bạn biết/nhớ những gì được lưu
giữ:
Cookie là một bản ghi dữ liệu thuần văn bản của 5 trường biến:
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 190
Expires : Ngày mà Cookie sẽ hết hạn. Nếu để trống, Cookie sẽ hết hạn khi khách truy cập
thoát khỏi trình duyệt.
Domain : Tên miền của site của bạn
Path : Path tới thư mục hoặc Webpage mà thiết lập Cookie đó. Nó có thể là trống nếu bạn
muốn thu nhận Cookie từ bất kỳ thư mục hoặc trang nào.
Secure : Nếu trường này chứa từ “secure”, thì Cookie chỉ có thể được thu hồi với một
Secure Server. Nếu trường này để trống, sẽ không tồn tại hạn chế nào.
Name=Value : Cookie được thiết lập và thu hồi trong form các cặp key/value.
Thiết lập Cookie
Rất dễ dàng để gửi Cookie tới trình duyệt. Những Cookie này được gửi cùng với HTTP Header ở
trước trường Content-type. Giả sử bạn muốn thiết lập UserID và Password ở dạng Cookie. Thì
thiết lập Cookie sẽ được thực hiện như sau:
#include
using namespace std;
int main ()
{
cout << "Set-Cookie:UserID=XYZ;\r\n";
cout << "Set-Cookie:Password=XYZ123;\r\n";
cout << "Set-Cookie:Domain=www.tutorialspoint.com;\r\n";
cout << "Set-Cookie:Path=/perl;\n";
cout << "Content-type:text/html\r\n\r\n";
cout \n";
cout \n";
cout Cookies in CGI\n";
cout \n";
cout \n";
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 191
cout << "Setting cookies" << endl;
cout \n";
cout \n";
cout \n";
return 0;
}
Từ ví dụ này, bạn phải hiểu cách thiết lập Cookie. Chúng ta sử dụng HTTP Header là Set-
Cookie để thiết lập các Cookie.
Ở đây, nó là tùy ý để thiết lập các thuộc tính của Cookie như Expires, Domain, và Path. Bạn nhớ
rằng, Cookie được thiết lập trước khi gửi dòng sau: "Content-type:text/html\r\n\r\n.
Biên dịch chương trình trên để tạo setcookies.cgi. Nó sẽ thiết lập 4 Cookie tại máy tính của bạn.
Thu hồi Cookie
Việc thu hồi tất cả Cookie đã thiết lập là khá dễ dàng. Cookie được lưu giữ trong biến môi trường
CGI là HTTP_COOKIE và chúng sẽ có form sau:
key1=value1;key2=value2;key3=value3....
Dưới đây là ví dụ về cách thu hồi các Cookie:
#include
#include
#include
#include
#include
#include
#include
#include
#include
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 192
using namespace std;
using namespace cgicc;
int main ()
{
Cgicc cgi;
const_cookie_iterator cci;
cout << "Content-type:text/html\r\n\r\n";
cout \n";
cout \n";
cout Cookies in CGI\n";
cout \n";
cout \n";
cout ";
// get environment variables
const CgiEnvironment& env = cgi.getEnvironment();
for( cci = env.getCookieList().begin();
cci != env.getCookieList().end();
++cci )
{
cout " getName() ";
cout getValue();
cout \n";
}
cout <\n";
cout \n";
cout \n";
cout \n";
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 193
return 0;
}
Bây giờ, biên dịch chương trình trên để tạo getcookies.cgi, và thử lấy danh sách tất cả Cookie có
sẵn tại máy tính của bạn.
Nó sẽ cho một danh sách gồm 4 Cookie đã được thiết lập ở phần trước và tất cả Cookie khác
được thiết lập tại máy tính của bạn:
UserID XYZ
Password XYZ123
Domain www.tutorialspoint.com
Path /perl
Ví dụ về File Upload
Để tải một file lên, HTML code phải có thuộc tính enctype được thiết lập là multipart/form-data.
Thẻ input với kiểu file này sẽ tạo một nút “Browse”.
<form enctype="multipart/form-data"
action="/cgi-bin/cpp_uploadfile.cgi"
method="post">
File:
Kết quả của code trên sẽ là form sau:
File:
Upload
Ghi chú: Ví dụ trên đã bị vô hiệu hóa để tránh người dùng Upload file lên Server của chúng tôi.
Nhưng bạn có thể thử code trên với Server của bạn.
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 194
Đây là chương trình cpp_uploadfile.cpp để xử lý upload file:
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cgicc;
int main ()
{
Cgicc cgi;
cout << "Content-type:text/html\r\n\r\n";
cout \n";
cout \n";
cout File Upload in CGI\n";
cout \n";
cout \n";
// get list of files to be uploaded
const_file_iterator file = cgi.getFile("userfile");
if(file != cgi.getFiles().end()) {
// send data type at cout.
cout getDataType());
// write content at cout.
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 195
file->writeToStream(cout);
}
cout \n";
cout \n";
cout \n";
return 0;
}
Ví dụ trên đang viết nội dung tại cout stream, nhưng bạn có thể mở file stream của bạn và giữ nội
dung của upload file trong một file tại vị trí mong muốn.
Thư viện Template chuẩn (STL) trong
C++
Hy vọng bạn đã hiểu khái niệm về Template trong C++ đã được chúng tôi trình bày trong chương
về Template. Standard Tamplate Library (STL) trong C++ là một tập hợp các lớp Template mạnh
mẽ trong C++ để cung cấp các lớp và các hàm được tạo theo khuân mẫu cho mục đích lập trình
tổng quát, mà triển khai nhiều thuật toán và cấu trúc dữ liệu được sử dụng phổ biến và thông dụng
như vector, list, queue và stack.
Có ba thành phần mang tính cấu trúc mạnh mẽ của Standard Tamplate Library (STL) trong C++ là:
Thành phần Miêu tả
Containers Containers được sử dụng để quản lý các tập hợp đối tượng của
một kiểu cụ thể. Có một số kiểu Containers khác nhau như list,
vector, map,
Algorithms Algorithms hoạt động trên containers. Chúng cung cấp các
phương thức mà theo đó bạn sẽ thực hiện việc khởi tạo, sắp
xếp, tìm kiếm nội dung của Containers
Iterators Iterators được sử dụng để duyệt qua các phần tử trong tập hợp
các đối tượng. Những tập hợp này có thể là Containers hoặc
Subset của Containers
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 196
Chúng ta sẽ đề cập về 3 thành phần của STL trong C++ trong chương tiếp theo khi bàn luận về
Thư viện chuẩn C++ (C++ Standard Library). Bây giờ, bạn ghi nhớ rằng, 3 thành phần này có một
tập hợp các hàm được định nghĩa trước, mà giúp chúng ta trong việc thực hiện các tác vụ phức tạp
trở nên đơn giản hơn.
Xét ví dụ sau minh họa vector containers (là một Template chuẩn trong C++), mà giống như một
mảng với một exception mà tự động xử lý các nhu cầu về storage của riêng nó khi nó cần:
#include
#include
using namespace std;
int main()
{
// create a vector to store int
vector vec;
int i;
// display the original size of vec
cout << "vector size = " << vec.size() << endl;
// push 5 values into the vector
for(i = 0; i < 5; i++){
vec.push_back(i);
}
// display extended size of vec
cout << "extended vector size = " << vec.size() << endl;
// access 5 values from the vector
for(i = 0; i < 5; i++){
cout << "value of vec [" << i << "] = " << vec[i] << endl;
}
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 197
// use iterator to access the values
vector::iterator v = vec.begin();
while( v != vec.end()) {
cout << "value of v = " << *v << endl;
v++;
}
return 0;
}
Khi code trên được biên dịch và thực thi, nó cho kết quả sau:
vector size = 0
extended vector size = 5
value of vec [0] = 0
value of vec [1] = 1
value of vec [2] = 2
value of vec [3] = 3
value of vec [4] = 4
value of v = 0
value of v = 1
value of v = 2
value of v = 3
value of v = 4
Dưới đây là các điểm quan trọng cần ghi nhớ liên quan tới các hàm đa dạng đã được sử dụng
trong ví dụ trên:
Hàm thành viên push_back() chèn giá trị tại phần cuối của vector, mở rộng kích cỡ của nó
khi cần.
Hàm size() hiển thị kích cỡ của vector.
Hàm begin() trả về một iterator tới phần đầu của vector.
Hàm end() trả về một interator tới phần cuối của vecor.
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 198
Thư viện chuẩn C++ (C++ Standard
Library)
Thư viện chuẩn C++ (C++ Standard Library) có thể chia thành hai phần:
Thư viện hàm chuẩn trong C++ (Standard Function Library): Thư viện này gồm các
hàm mang mục đích tổng quát mà không là một phần của bất kỳ lớp nào. Thư viện hàm
chuẩn là kế thừa từ C.
Thư viện lớp hướng đối tượng trong C++ (Object Oriented Class Library): Đây là một
tập hợp của các lớp và các hàm liên kết.
Thư viện chuẩn C++ cũng kết hợp chặt chẽ Thư viện chuẩn C, với một sự bổ sung và thay đổi nhỏ
để hỗ trợ tính an toàn kiểu (type safety).
Thư viện hàm chuẩn trong C++ (Standard Function
Library)
Thư viện hàm chuẩn trong C++ được phân chia thành:
I/O
Xử lý chuỗi và ký tự
Toán học
Date, Time và vị trí
Cấp phát động
Hỗn hợp
Các hàm cho wide-character
Thư viện lớp hướng đối tượng trong C++ (Object
Oriented Class Library)
Thư viện hướng đối tượng chuẩn C++ định nghĩa một tập hợp rộng rãi các lớp mà cung cấp sự hỗ
trợ cho các hoạt động phổ biên, gồm xử lý I/O, String, số. Thư viện này bao gồm:
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 199
Các lớp I/O chuẩn C++
Lớp String
Lớp thuộc số
Lớp STL Container
Lớp STL Algorithm
Các đối tượng STL Function
STL Iterator
STL Allocator
Thư viện Localization
Các lớp Exception Handling
Thư viện hỗ trợ hàm hỗn hợp
Tài liệu tham khảo C++
Dưới đây là các nguồn chứa các tài liệu tham khảo về C++ hữu ích. Mong bạn sử dụng chúng để
hiểu sâu hơn các khái niệm đã được trình bày trong loạt bài này.
Link hữu ích về C++
Tutorialspoint − Loạt bài hướng dẫn của chúng tôi xây dựng dựa trên nguồn này.
C++ Programming Language Tutorials − Loạt bài hướng dẫn về Ngôn ngữ lập trình C++
C++ Programming − Sách này về C++ và tính tương tác của nó với thiết kế phần mềm và
sự sử dụng ngôn ngữ C++ trong cuộc sống thực.
C++ FAQ − Câu hỏi thường xuyên về C++
Free Country − Cung cấp source code về C++ miễn phí và thư viện C++ cho một số
chương trình như lập trình game, thư viện Template chuẩn và lập trình GUI.
Copyright © vietjack.com
Trang chia sẻ các bài học online miễn phí Trang 200
C and C++ Users Group − Cung cấp source code từ các dự án về C++ trong các lĩnh vực
lập trình đa dạng: AI, Animation, Compiler, Database, Debugging, Encryption, Game,
Graphics, GUI,
Các file đính kèm theo tài liệu này:
- tai_lieu_lap_trinh_c_tieng_viet_8156.pdf