Nhờ giúp đỡ vấn đề trong chương trình người treo cổ viết bằng C
Chào các bạn, mình đang học c theo 1 tài liệu trên diễn đàn , và đang học tới phần cuối của tài liệu đó là viết chương trình người treo cổ .
Ok, mình có 2 vấn đề như thế này, mong các bạn giải đáp
1 ví dụ bây giờ mình muốn đưa ra một gợi ý là từ bí mật cần đoán có số lượng bao nhiêu ký tự và hiển thị sẳn một ký tự để cho người chơi đoán thì nên làm như thế nào ? mình nghĩ mãi mà không ra cách , mong các bạn hướng dẫn giúp mình
2 Trong tài liệu có nói thêm là thêm vào mục hỏi người chơi có muốn tiếp tục không , mình đã thử dùng vòng lặp bao quát toàn bộ chương trình , rồi thử dùng lệnh goto, continue … mà vẫn gặp phải lỗi , mình sẽ nêu ngay ở dưới.
Ok sau đây là toàn bộ cấu trúc code
file main.c
và mình gặp vấn đề ngay tại đây, ví dụ bây giờ khi mình đoán ra được từ bí mật , mình ấn phím 1 hoặc 0 thì chương trình vẫn hoạt động tốt, chương trình vẫn quay ngược lên đầu vòng lặp, nhưng khi mình cố tình nhập hết lượt để thua, thì khi mình nhấn phím 1 chương trình chỉ hiện ra dòng printf("
-----Welcome To The Hangman Game--------
");
và phần lệnh trong else, và cứ thế tiếp tục cho tới khi mình nhấn 0 để thoát chương trình, đó là vấn đề mình đang gặp phải, mong các bạn giúp đỡ giải đáp.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "danhmuc2.h"
char docKytu();
int win(int[],long);
int kiem_tra_ky_tu(char,char[],int[]);
int main()
{
char ky_tu = 0; //biến này lưu trữ ký tự;
char ky_tu_bi_mat[100] = {0}; //từ cần đoán
int *so_ky_tu_bi_mat = NULL; // 1 mảng dạng boolean, mỗi ô tương ứng với 1 ký tự đc đoán, đúng trả về 1, sai trả về 0
int so_lan_doan = 10; // số lượt
int i = 0; //biến hỗ trợ
long do_dai_tu = 0; //lưu giá trị thể hiện độ dài cùa từ
int tiep_tuc_game;
while(tiep_tuc_game == 1 || tiep_tuc_game !=0)
{
if(!chon_tu(ky_tu_bi_mat))
exit(0);
do_dai_tu = strlen(ky_tu_bi_mat);
so_ky_tu_bi_mat = malloc(do_dai_tu*sizeof(int)); // cấp phát bộ nhớ
if(so_ky_tu_bi_mat == NULL)
exit(0);
for(i = 0;i<do_dai_tu;i++)
so_ky_tu_bi_mat[i] = 0;
printf("
-----Welcome To The Hangman Game--------
");
while(so_lan_doan>0 &&!win(so_ky_tu_bi_mat,do_dai_tu))
{
printf("
Ban %d luot doan",so_lan_doan);
for(i = 0;i<do_dai_tu;i++)
{
if(so_ky_tu_bi_mat[i]) //nếu người chơi tìm thấy ký tự i
printf("%c",ky_tu_bi_mat[i]); // hiển thị ký tự
else
printf("*");
}
printf("
tu bi mat la gi?
");
printf("
moi ban nhap vao ky tu bi mat
");
ky_tu = docKytu();
if(!kiem_tra_ky_tu(ky_tu,ky_tu_bi_mat,so_ky_tu_bi_mat))
{
so_lan_doan--;
}
}
if(win(so_ky_tu_bi_mat,do_dai_tu))
{
printf("
Xin chuc mung, ban da thang, tu bi mat la %s",ky_tu_bi_mat);
}
else
{
printf("
Xin chia buon, ban da thua, tu bi mat la %s
",ky_tu_bi_mat);
}
free(so_ky_tu_bi_mat);
printf("
Ban co muon tiep tuc :D
");
printf("
An 1 de tiep tuc: ");
printf("
An 0 de dung lai: ");
scanf("%d",&tiep_tuc_game);
}
return 0;
}
char docKytu()
{
char ky_tu_nhap_vao = 0;
ky_tu_nhap_vao = getchar(); //đọc ký tự được nhập vào đầu tiên
ky_tu_nhap_vao = toupper(ky_tu_nhap_vao); //viet hoa ký tự
//lần lượt đọc từng ký tự cho đến khi xuống dòng
while(getchar()!='
');
return ky_tu_nhap_vao; //trả về ký tự đọc được
}
int win(int so_ky_tu_bi_mat[],long do_dai_tu)
{
int i = 0;
int nguoi_choi_win = 1;
for(int i = 0;i<do_dai_tu;i++)
{
if(so_ky_tu_bi_mat[i]==0)
nguoi_choi_win = 0;
}
return nguoi_choi_win;
}
int kiem_tra_ky_tu(char ky_tu, char ky_tu_bi_mat[],int so_ky_tu_bi_mat[])
{
int i = 0;
int ky_tu_chinh_xac = 0;
for(i = 0;ky_tu_bi_mat[i]!=' ';i++)
{
if(ky_tu == ky_tu_bi_mat[i])//nếu ký tự có chứa trong mảng ký tự bí mật
{
ky_tu_chinh_xac = 1; //ký tự sẽ đc lưu lại thể hiện nó là ký tự chính xác
so_ky_tu_bi_mat[i] = 1; //Gửi giá trị 1 vào ô tương ứng với vị trí của ký tự đó trong mảng
}
}
return ky_tu_chinh_xac;
}
còn đây là cấu trúc code filedanhmuc.c
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "danhmuc.h"
int chon_tu(char *tu_duoc_chon)
{
FILE *danhmuc = NULL;
int stt_cua_ky_tu = 0, stt_cua_ky_tu_duoc_chon = 0, i = 0;
int save_ky_tu = 0;
danhmuc = fopen("danhmuc.txt","r"); //tạo tập tin với mode read-only
if(danhmuc == NULL)
{
printf("
File chua duoc tao
");
return 0; //trả về 0 nếu mở thất bại, kết thúc hàm
}
do
{
save_ky_tu = fgetc(danhmuc);
if(save_ky_tu == '
')
stt_cua_ky_tu++;
}while(save_ky_tu!=EOF);
stt_cua_ky_tu_duoc_chon = tu_ngau_nhien(stt_cua_ky_tu); // hàm này chọn 1 từ ngẫu nhiên
rewind(danhmuc);
// chương trình đọc từ đầu và ngừng lại khi tìm thấy từ được chọn
while(stt_cua_ky_tu_duoc_chon>0)
{
save_ky_tu = fgetc(danhmuc);
if(save_ky_tu == '
')
stt_cua_ky_tu_duoc_chon--;
}
fgets(tu_duoc_chon,100,danhmuc);
tu_duoc_chon[strlen(tu_duoc_chon)-1] = ' ';
fclose(danhmuc);
return 1;
}
int tu_ngau_nhien(int stt_max)
{
srand(time(NULL));
return (rand()%stt_max);
}
cấu trúc file danhmuc.h
#ifndef DEF_DANHMUC // nếu const này chưa được xác định , file này chưa được tạo
#define DEF_DANHMUC // Ta xác định const để lần sau file sẽ không đưa vào nữa
int chon_tu(char *tu_duoc_chon);
int tu_ngau_nhien(int stt_max);
#endif // DEF_DANHMUC
Nội dung file danhmuc.txt
đây là file chứa các từ bí mật
LOVE
MONEY
PROGRAM
FUNCTION
POINTER
LOOP
INSTRUCTION
STRING
VARIABLE
CONSTANT
DEFINE
về code thì không có gì sai cả, chỉ là nó gặp phải một số vấn đề trên thôi, rất mong được giúp đỡ, xin cảm ơn
Hi Hoài Nam Trương.
1 Để sửa lỗi bạn dùng công cụ bắt bọ để theo dõ xem chuyện gì sảy ra.
2 Không nên dùng goto.
P/S Bạn nên xem qua về kiến trúc của chương trình game.
là debug phải không bạn ?
Hi Hoài Nam Trương.
Không là BẮT BỌ
nghĩa là sao bạn ? bắt bọ nghĩa là gì .
Cái ông @Phong_Ky_Vo cứ loanh quanh mãi chung quy lại vẫn là debug code và tránh dùng goto thôi :v
ths bác, bác trên nói bắt bọ làm mình cứ tưởng là gì không
Hi Hoài Nam Trương.
là BẮT BỌ
Cái này là rộng hơn bắt bọ rồi. Nói đúng hơn, đây là vấn đề phẫu thuật thẩm mỹ code.
Mình cũng đến “Muốn treo cổ” luôn rồi. Code mình cũng không khác gì của bạn. Nhưng chữ cái mà mình đoán đầu tiên nó luôn luôn sai dù là chữ đó có trong từ bí mật, khi đoán chữ đó lần thứ hai thì nó mới được. Của mình bị vấn đề là lần đoán đầu tiên nó luôn luôn sai, kể từ lần đoán thứ hai thì tất cả bình thường. Vậy có bạn nào chỉ cho mình với…!!
Up code lên bạn ơi. Bạn cứ nói thế này suông thì không ai biết bạn sai ở đâu cả.
giống y chang trên kia luôn, khác mỗi cách đặt tên biến số thoi
Bạn up cả đống code thế này, thực sự mình sống không nổi
Thiếu
&
Vòng for sai 1 điều kiện, phải là
< doDaiTuBM
. Và không chỉ có 1 chỗ sai như thế này:Nếu đây là dòng bạn khởi tạo từ bí mật thì hãy đưa nó ra ngoài vòng while do.
Mình chịu code của bạn thôi.
Rất cảm ơn ý kiến của bạn!
scanf("%s",&datTuBM);
nếu thêm&
thì có lỗi ngay tại bước đó.Hai ý của bạn về khai báo và vòng lặp
for
thì đúng rồiNhưng vấn đề của mình như đã nói ngay từ đầu thì vẫn chưa thể giải quyết được.
Bạn hãy xem
scanf không có & mới là có lỗi. Còn có mà sinh lỗi thì do datTuBM của bạn không phải là string.
vậy mình khai báo thế này đúng không v??
Ok rồi. Dòng 77 của bạn chỉ bị warning thôi. Bạn có thể google để xem kĩ hơn nguyên nhân tại sao bị warning.
Ủa dòng 77 phải bỏ dấu & đi khi scanf chứ nhỉ?
scanf mà bỏ & thì gọi éo gì là scanf nữa @@
warning ở kiểu dữ liệu (argument 2) cơ mà :v
theo em nhớ nếu như char kiểu đó thì & là char, còn không có & là char *. Tại nếu mà & là nó chỉ nạp vô cái chữ cái đầu tiên thôi, còn bỏ là nạp hết, đây là %s
Anh viết code C có & này: