Kiểm tra ngày nhập vào ĐÚNG hay SAI dựa vào tháng và năm

Viết chương trình nhập vào từ bàn phím ba giá trị là ngay, thang, nam biểu thị là ngày, tháng, năm nào đó; Kiểm tra xem các giá trị này có biểu diễn hợp lệ một giá trị ngày hay không? Nếu hợp lệ, kết quả là YES, nếu không kết quả là NO.
Code:

#include<stdio.h>
int main()
{
    int ngay, thang, nam, ngaydungcuathang;
    scanf("%d%d%d", &ngay, &thang, &nam);
    if(nam < 1 || (thang < 1 || thang > 12)){
        printf("NO");
    }
    switch(thang)
    {   case 1:     
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
        ngaydungcuathang = 31;
        break;
        case 4:
        case 6:
        case 9:
        case 11:
        ngaydungcuathang = 30;
        case 2:
                if(nam % 400 == 0 || (nam % 4 == 0 && !(nam % 100 == 0 )))
                {   ngaydungcuathang = 29;
                    else
                    ngaydungcuathang = 28;}
        break;
    }
    if(ngay >= 1 && ngay <= ngaydungcuathang){
        printf("YES");}
    printf("NO");
}

Các Bác xem giúp em đoạn code này em code sai ở dòng nào với ạ, em sửa và biên dịch mãi vẫn báo lỗi liên tục ạ. :sob: Em cảm ơn.

quên break nè :V :V :V

3 Likes

Em thêm break vào rồi vẫn báo lỗi tại dòng if else của “CASE 2” ạ.

break ở trên case 2 ấy :V :V

à cái lỗi đó là do if else phải viết là
if (…) {…} else {…} chứ,
của em hiện tại là
if (…) { else … }

3 Likes

:rofl: .Em vừa sửa lại, nhưng khi biên dịch và nhập 21 19 2020 lại ra kết quả là NONO mà không phải là NO bác ạ.

chắc do cái switch ko có default case nên ngaydungcuathang nó chứa giá trị rác nên mới in ra cái no thứ 2 :V

lúc print no đầu tiên thì return 1; thoát khỏi chương trình luôn là được :relieved:

ở dưới viết switch là

switch (...) {
case ...:
case ...:
  ngaydungcuathang = ...;
  break; 
case ...:
case ...:
  ngaydungcuathang = ...;
  break; 
case 2:
  ...
  break; 
default:
  ngaydungcuathang = -1; // hoặc in ra print("Tháng dỏm\n");
  break;
}
2 Likes

ngaydungcuathang = -1 sao chỗ này lại là trừ 1 vậy bác ạ.
Em thử sửa lại theo cách bác cho return = 1 nó ra NO ạ. :heart_eyes:

#include<stdio.h>
int main()
{
    int ngay, thang, nam, ngaydungcuathang;
    scanf("%d%d%d", &ngay, &thang, &nam);
    if(nam < 1 || (thang < 1 || thang > 12)){
        printf("NO");
        return 1;
    }
    switch(thang)
    {   case 1:     
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
        ngaydungcuathang = 31;
        break;
   		case 2:
                if(nam % 400 == 0 || (nam % 4 == 0 && !(nam % 100 == 0 )))
                {   ngaydungcuathang = 29;}
                    else
                { ngaydungcuathang = 28;}
        break;
        default: ngaydungcuathang = 30; break;
    }
   if(ngay >= 1 && ngay <= ngaydungcuathang){
        printf("YES");}
    printf("NO");
}

mấy cái case kia sao lộn tùng phèo hết rồi :V tháng 30 ngày đâu

à default case cho 31 ngày cũng đúng, khỏi mất công gán số -1 :kissing_closed_eyes:

case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
  ngaydungcuathang = 31;
  break;
case 2:
  ngaydungcuathang = 28;
  if (...) ngaydungcuathang = 29;
  break;
default:
  ngaydungcuathang = 30;
  break;
3 Likes

À, em vừa sửa lại rồi ạ. Nhưng khi nhập ngày 30 4 2020 lại ra YESNO mà không phải là YES ạ. Em có thêm “return 1” tại đoạn code dưới thì ra YES ạ. Đối với bài toán này có cách viết hợp lệ như nào khi biên dịch và xuất ra không cần dùng lệnh return không Bác ạ?

if(ngay >= 1 && ngay <= ngaydungcuathang){
        printf("YES");
        return 1;
		}
    printf("NO");

thêm else vào

if(ngay >= 1 && ngay <= ngaydungcuathang) {
        printf("YES");
        return 1;
}
else {
    printf("NO");
}

em học hàm chưa :V viết tách nó ra thành 1 hàm

bool laNgayHopLe(int ngay, int thang, int nam);

hoặc xài tiếng Anh cho mọi người đọc được :V

bool isValidDate(int day, int month, int year);

trong main chỉ xử lý input day/month/year rồi quăng 3 số này vào hàm isValidDate là xong, trả về true nếu hợp lệ, false nếu ko hợp lệ

int main() {
  int day, month, year;
  scanf("%d%d%d", &day, &month, &year);

  if (isValidDate(day, month, year)) {
    puts("YES");
  } else {
    puts("NO");
  }

  // hoặc ngắn gọn xài ?:
  // puts(isValidDate(day, month, year) ? "YES" : "NO");
}

trong hàm isValidDate khúc tính ngaydungcuathang tách nó ra thành hàm khác nữa:

int daysInMonth(int month, int year);

chỗ ktra năm nhuận lại tách ra thành hàm nữa:

bool isLeapYear(int year);

thậm chí check tháng 1-12 cũng có thể tách ra thành hàm riêng :V

bool isValidMonth(int month);

thì hàm isValidDate chỉ còn đơn giản là

bool isValidDate(int day, int month, int year) {
  if (year < 1 || !isValidMonth(month)) return false;
  // int dim = daysInMonth(month, year); // khỏi cần dòng này
  // thay vì viết if (###) return true; else return false; thì return thẳng ### luôn
  return 1 <= day && day <= daysInMonth(month, year);
}

để show off hơn nữa thì hàm daysInMonth có thể ko xài switch case cũng được, xài 1 dòng này thôi :smiling_face_with_three_hearts:

int daysInMonth(int month, int year) {
  return (28 | 0x3bbeecc >> month * 2 & 3) + (month == 2 && isLeapYear(year));
}

tóm lại tách thành 4 hàm 1 dòng mỗi hàm là được :smiling_face_with_three_hearts:

edit:

month["\0\x1f\x1c\x1e\x1f\x1e\x1f\x1f\x1f\x1e\x1f\x1e\x1f"] 

cũng thay thế 1 dòng 0x3bbeecc kia được nè :smiling_face_with_three_hearts:

4 Likes

Em thêm else vào ra kết quả chuẩn rồi ạ. Cảm ơn Bác nhiều nha. Em vừa tự học tới phần cấu trúc rẽ nhánh thôi ạ.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?