Nhắc lại:
Chương trình chưa hoàn hảo thật sự:
- Mảng sinhVien[] là cho sẵn, chúng ta cần thật sự là một mảng bất kỳ do người sử dụng nhập vào
- Tổng số phần tử của mảng mặc định là 3, nếu số sinh viên khác thì chương trình sẽ hoạt động sai.
Chúng ta cần biết kích thước của mảng. Tức là ta cần biết số sinh viên. Đơn giản là hỏi người sử dụng và lưu vào một biến. Để bạn quen với cách viết hàm, chúng ta sử dụng hàm cho công việc "dễ ẹc" này
Chúng ta cần một hàm mà giá trị trả về sẽ là một số nguyên int, đai diện cho số sinh viên.
Khai báo hàm sẽ như sau, chúng ta đặt trên main()
// Khai báo hàm 2
int soSinhVien();
Định nghĩa hàm, chúng ta sẽ đặt dưới main()
// Định nghĩa hàm 2
int soSinhVien(){
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
return 1;
}
Sau khi thêm vào, chương trình sẽ như sau
#include <stdio.h>
// Khai báo hàm
void danhSach(char *sinhVien[]);
// Khai báo hàm 2
int soSinhVien();
int main()
{
char *sinhVien[] = {"Nguyen Van A",
"Tran Van B", "Le Thi C"};
danhSach(sinhVien);
return 0;
}
// Định nghĩa hàm
void danhSach(char *sinhVien[]) {
printf("Xin chào Dat Viet Lap Trinh! Danh sach Sinh Vien:\n");
for (int i = 0; i < 3; i++)
{
printf("%s\n", sinhVien[i]);
}
}
// Định nghĩa hàm 2
int soSinhVien(){
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
return 1;
}
Chúng ta sẽ chạy thử chương trình. Mọi thứ đều ổn
Bây giờ ta sẽ định nghĩa hàm.
- Chúng ta khai báo một biến int tongSo;
- Sau đó dùng lệnh scanf để nhận dữ liệu người dùng nhập vào.
- Cuối cùng dùng lệnh return tongSo;
Đến lúc này, chương trình sẽ như sau:
#include <stdio.h>
// Khai báo hàm
void danhSach(char *sinhVien[]);
// Khai báo hàm 2
int soSinhVien();
int main()
{
char *sinhVien[] = {"Nguyen Van A",
"Tran Van B", "Le Thi C"};
danhSach(sinhVien);
return 0;
}
// Định nghĩa hàm
void danhSach(char *sinhVien[]) {
printf("Xin chào Dat Viet Lap Trinh! Danh sach Sinh Vien:\n");
for (int i = 0; i < 3; i++)
{
printf("%s\n", sinhVien[i]);
}
}
// Định nghĩa hàm 2
int soSinhVien(){
int tongSo;
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
printf("Hãy nhập tổng số sinh viên: ");
scanf("%d", &tongSo);
return tongSo;
}
Bấm Run để chạy chương trình, mọi thứ ổn. Tuy nhiên ta cần kiểm tra xem hàm có hoạt động đúng không. Ta cần thêm một lệnh printf và lời gọi hàm.
#include <stdio.h>
// Khai báo hàm
void danhSach(char *sinhVien[]);
// Khai báo hàm 2
int soSinhVien();
int main()
{
char *sinhVien[] = {"Nguyen Van A",
"Tran Van B", "Le Thi C"};
danhSach(sinhVien);
soSinhVien();
return 0;
}
// Định nghĩa hàm
void danhSach(char *sinhVien[]) {
printf("Xin chào Dat Viet Lap Trinh! Danh sach Sinh Vien:\n");
for (int i = 0; i < 3; i++)
{
printf("%s\n", sinhVien[i]);
}
}
// Định nghĩa hàm 2
int soSinhVien(){
int tongSo;
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
printf("Hãy nhập tổng số sinh viên: ");
scanf("%d", &tongSo);
printf("Tong so sinh vien là : %d\n", tongSo);
return tongSo;
}
Bấm Run để chạy chương trình. Mọi thứ rất ổn.
#include <stdio.h>
// Khai báo hàm
void danhSach(char *sinhVien[]);
// Khai báo hàm 2
int soSinhVien();
int main()
{
char *sinhVien[] = {"Nguyen Van A",
"Tran Van B", "Le Thi C"};
int size;
size = soSinhVien();
danhSach(sinhVien);
//soSinhVien();
return 0;
}
// Định nghĩa hàm
void danhSach(char *sinhVien[]) {
printf("Xin chào Dat Viet Lap Trinh! Danh sach Sinh Vien:\n");
for (int i = 0; i < 3; i++)
{
printf("%s\n", sinhVien[i]);
}
}
// Định nghĩa hàm 2
int soSinhVien(){
int tongSo;
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
printf("Hãy nhập tổng số sinh viên: ");
scanf("%d", &tongSo);
printf("Tong so sinh vien là : %d\n", tongSo);
return tongSo;
}
Ta sẽ khai báo một mảng con trỏ sinhVien2[] với kích thước là size;
char *sinhVien2[size];
char hoTen[30];
#include <stdio.h>
// Khai báo hàm
void danhSach(char *sinhVien[]);
// Khai báo hàm 2
int soSinhVien();
int main()
{
char *sinhVien[] = {"Nguyen Van A",
"Tran Van B", "Le Thi C"};
int size;
size = soSinhVien();
char *sinhVien2[size];
char hoTen[30];
for(int i = 0; i < size; i++){
printf("Nhap Ho Va Ten Sinh Vien[%d] :\n ", i);
fgets(hoTen, sizeof(hoTen), stdin);
printf("Xin chao: %s", hoTen);
}
danhSach(sinhVien);
return 0;
}
// Định nghĩa hàm
void danhSach(char *sinhVien[]) {
printf("Xin chào Dat Viet Lap Trinh! Danh sach Sinh Vien:\n");
for (int i = 0; i < 3; i++)
{
printf("%s\n", sinhVien[i]);
}
}
// Định nghĩa hàm 2
int soSinhVien(){
int tongSo;
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
printf("Hãy nhập tổng số sinh viên: ");
scanf("%d", &tongSo);
printf("Tong so sinh vien là : %d\n", tongSo);
return tongSo;
}
Khi nhập chuỗi ký tự có dấu cách bằng hàm gets() hoặc fgets() thì đôi khi bạn sẽ xảy ra trường hợp bạn chưa kịp nhập nội dung cho chuỗi thì câu lệnh đã được bỏ qua.
Nguyên nhân xảy ra trôi lệnh : hàm gets() (hay fgets()) chỉ dừng nhập khi gặp kí tự xuống dòng. Coi lại chương trình: Trước khi lệnh fgets() thực hiện thì hàm soSinhVien(); đã được gọi và gán giá trị cho biến size. Khi người dùng nhập tổng số sinh viên và nhấn Enter.
Khi hàm fgets() đọc dữ liệu từ luồng vào sẽ gặp phải phím enter dư thừa này và nó sẽ dừng nhập vì bản chất nó gặp enter là dừng. Vì thế nội dung của mảng ký tự bạn định nhập chưa hề có ký tự nào mà câu lệnh fgets() đầu tiên trong vòng lặp For bị trôi qua luôn.
Cách xử lý : Có nhiều cách xử lý tình trạng trôi lệnh, nhưng về bản chất thì ta cần loại bỏ phím enter dư thừa trước khi nhập chuỗi.
Cách 1 : Dùng hàm getchar() để đọc 1 ký tự từ bàn phím, hàm này sẽ đọc phím enter thừa.
Cách 2 : Sử dụng câu lệnh scanf("\n"). Câu lệnh này sẽ bỏ qua mọi ký tự là dấu cách và enter cho tới khi bạn nhập kí tự khác dấu cách và enter.
Chúng ta sẽ sử dụng cách 2 trong chương trình của chúng ta. Bạn thêm lệnh hàm scanf("\n"); vào trước fgets(). Đây là chương trình
#include <stdio.h>
// Khai báo hàm
void danhSach(char *sinhVien[]);
// Khai báo hàm 2
int soSinhVien();
int main()
{
char *sinhVien[] = {"Nguyen Van A",
"Tran Van B", "Le Thi C"};
int size;
size = soSinhVien();
char *sinhVien2[size];
char hoTen[30];
for(int i = 0; i < size; i++){
printf("Nhap Ho Va Ten Sinh Vien[%d] :\n ", i);
scanf("\n");
fgets(hoTen, sizeof(hoTen), stdin);
printf("Xin chao: %s", hoTen);
}
danhSach(sinhVien);
return 0;
}
// Định nghĩa hàm
void danhSach(char *sinhVien[]) {
printf("Xin chào Dat Viet Lap Trinh! Danh sach Sinh Vien:\n");
for (int i = 0; i < 3; i++)
{
printf("%s\n", sinhVien[i]);
}
}
// Định nghĩa hàm 2
int soSinhVien(){
int tongSo;
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
printf("Hãy nhập tổng số sinh viên: ");
scanf("%d", &tongSo);
printf("Tong so sinh vien là : %d\n", tongSo);
return tongSo;
}
Chạy thử chương trình, bây giờ mọi thứ đã ổn.
#include <stdio.h>
// Khai báo hàm
void danhSach(char *sinhVien[]);
// Khai báo hàm 2
int soSinhVien();
int main()
{
char *sinhVien[] = {"Nguyen Van A",
"Tran Van B", "Le Thi C"};
int size;
size = soSinhVien();
char *sinhVien2[size];
char hoTen[30];
for(int i = 0; i < size; i++){
printf("Nhap Ho Va Ten Sinh Vien[%d] :\n ", i);
scanf("\n");
fgets(hoTen, sizeof(hoTen), stdin);
printf("Xin chao: %s", hoTen);
sinhVien2[i] = hoTen;
}
for(int i = size - 1; i >= 0; i--){
printf("%s ", sinhVien2[i]);
}
danhSach(sinhVien);
return 0;
}
// Định nghĩa hàm
void danhSach(char *sinhVien[]) {
printf("Xin chào Dat Viet Lap Trinh! Danh sach Sinh Vien:\n");
for (int i = 0; i < 3; i++)
{
printf("%s\n", sinhVien[i]);
}
}
// Định nghĩa hàm 2
int soSinhVien(){
int tongSo;
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
printf("Hãy nhập tổng số sinh viên: ");
scanf("%d", &tongSo);
printf("Tong so sinh vien là : %d\n", tongSo);
return tongSo;
}
Trước hết chúng ta xóa dòng lệnh sinhVien2[i] = hoTen; thêm thư viện <string.h> vào đầu chương trình. Sau đó ta dùng hàm strndup như sau:
sinhVien2[i] = strndup(hoTen,30);
Đây là chương trình đã sửa lại.
#include <stdio.h>
#include <string.h>
// Khai báo hàm
void danhSach(char *sinhVien[]);
// Khai báo hàm 2
int soSinhVien();
int main()
{
char *sinhVien[] = {"Nguyen Van A",
"Tran Van B", "Le Thi C"};
int size;
size = soSinhVien();
char *sinhVien2[size];
char hoTen[30];
for(int i = 0; i < size; i++){
printf("Nhap Ho Va Ten Sinh Vien[%d] :\n ", i);
scanf("\n");
fgets(hoTen, sizeof(hoTen), stdin);
printf("Xin chao: %s", hoTen);
sinhVien2[i] = strndup(hoTen,30);
}
for(int i = size - 1; i >= 0; i--){
printf("%s ", sinhVien2[i]);
}
danhSach(sinhVien);
return 0;
}
// Định nghĩa hàm
void danhSach(char *sinhVien[]) {
printf("Xin chào Dat Viet Lap Trinh! Danh sach Sinh Vien:\n");
for (int i = 0; i < 3; i++)
{
printf("%s\n", sinhVien[i]);
}
}
// Định nghĩa hàm 2
int soSinhVien(){
int tongSo;
printf("Xin chào Dat Viet Lap Trinh! Day la tong so Sinh Vien\n");
printf("Hãy nhập tổng số sinh viên: ");
scanf("%d", &tongSo);
printf("Tong so sinh vien là : %d\n", tongSo);
return tongSo;
}
Bấm Run để chạy chương trình, ta sẽ thấy mọi thứ đã đâu vào đó theo ý định của chúng ta.
Chúng ta sẽ tạm dừng ở đây, phần sau ta sẽ hoàn thiện chương trình.
Không có nhận xét nào:
Đăng nhận xét