Hàm strcmp không hoạt động trong vòng for

Xin lỗi mấy bác trước, bởi bài này em tự nghĩ ra đề nên không biết miêu tả nó như nào. Mong các bác thông cảm.

Input của để bài là nhập thứ, số lần nó xuất hiện, tháng năm rồi in ra ngày xuất hiện đó.
VD input: Thứ 3 lần thứ 4 của tháng 5 năm 2020
Output: 26/5/2020

Ý tưởng của em là duyệt 1 vòng for từ ngày đầu tháng đến ngày cuối tháng, nếu thấy ngày cần tìm thì cho ra output.
Đầu tiên em định cho 1 ngày làm mốc, để tìm thứ của các ngày khác. Nhưng nếu làm theo cách này thuật toán của em trở lên rất phức tạp, và cũng không cho ra kết quả (hàm strcmp không hoạt động giống với bài ở dưới). Nên em quyết định ăn gian bằng cách lên google, sau đó mò được công thức Julian Day Calculation, dùng để tìm thứ khi biết ngày, tháng, năm.

Đây là code của em. Hơi dài 1 chút, mong các bác thông cảm ạ.

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

bool checknhuan(int n) {
    if ((n % 4 == 0 && n % 100 != 0) || n % 400 == 0)
        return true;
    else return false;
}

int tinhngay(int m, int y) {
    switch (m) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            return 31;
        case 4:
        case 6:
        case 9:
        case 11:
            return 30;
        case 2:
            if (checknhuan(y))
                return 29;
            else
                return 28;
    }
}

const char *input(int n) {
    const char *t[] = {"Thu 2", 
        "Thu 3", 
        "Thu 4",
        "Thu 5", 
        "Thu 6", 
        "Thu 7", 
        "Chu nhat"};
    return t[n - 2];
}
const char *timthu(int d, int m, int y) {
    long i;
    i = (d + ((153 * (m + 12 * ((14 - m) / 12) - 3) + 2) / 5) +
        (365 * (y + 4800 - ((14 - m) / 12))) +
        ((y + 4800 - ((14 - m) / 12)) / 4) - 
        ((y + 4800 - ((14 - m) / 12)) / 100) + 
        ((y + 4800 - ((14 - m) / 12)) / 400)  - 32045) % 7;
    const char *s[] = {"Thu 2", 
        "Thu 3", 
        "Thu 4",
        "Thu 5", 
        "Thu 6", 
        "Thu 7", 
        "Chu nhat"};
    return s[i];
}

int main() {
    int s, k, i, j, d, m, y;
    printf ("Thu 2: 2");
    printf ("\nThu 3: 3");
    printf ("\nThu 4: 4");
    printf ("\nThu 5: 5");
    printf ("\nThu 6: 6");
    printf ("\nThu 7: 7");
    printf ("\nChu nhat: 8");
    printf ("\nBan muon tim thu may: ");
    do {
        scanf ("%d", &k);
        if (k < 2 || k > 8)
            printf ("Yeu cau nhap lai!\n");
    } while (k < 2 || k > 8);
    printf ("%s lan thu: ", input(k));
    scanf ("%d", &s);
    do {
        printf ("Cua thang: ");
        scanf ("%d", &m);
        if (m < 1 || m > 12)
            printf ("Thang khong hop le! Nhap lai!\n");
    } while (m < 1 || m > 12);
    do {
        printf ("Nam: ");
        scanf ("%d", &y);
    } while (y < 1 || y > 9999);
    
    for (i = 1; i <= tinhngay(m, y); i++) {
        if (strcmp(timthu(i, m, y), input(k)) == 0) {
            if ((i + 7 * (s - 1)) > tinhngay(m, y)) {
                printf (" Khong the tim %S lan thu %d cua thang %d, nam %d!", input(k), s, m, y);
                break;
            }
            if ((i + 7 * (s - 1)) <= tinhngay(m, y)) {
                d = i + 7 * (s - 1);
                printf ("%S lan thu %d cua thang %d, nam %d la ngay: %d/%d/%d", input(k), s, m, y, d, m, y);
                break;
            }
        }
    }
    getch();
}

Vấn đề ở đây ạ

for (i = 1; i <= tinhngay(m, y); i++) {
    if (strcmp(timthu(i, m, y), input(k)) == 0) {

Vì khi chạy em thấy chương trình kết thúc và thoát với code bằng 0 (không có lỗi gì).

Mấy bác cho em hỏi với bài toán như trên thì làm theo phương pháp nào là tốt nhất ạ? Nếu làm với phương pháp của em thì phải sửa thế nào để code có thể hoạt động?

Em cảm ơn các bác.

Bạn nói strcmp() không hoạt động. Bạn đang “vu khống” cho thứ không có tội. Lỗi là ở bạn nhé!
Bạn trả về giá trị khai báo trong hàm, ra khỏi hàm thì các giá trị bị hủy.
Cách bạn thực hiện cũng không hay, thay vì các hàm trả về chuỗi "Thu XX", bạn chỉ cần trả về số nguyên thể hiện của phần tử trong mảng “thứ” là xong.

4 Likes

Có vẻ như lỗi không nằm ở đây.
Em đã làm theo cách của bác nhưng chương trình vẫn không cho ra output = (
Bác xem hộ em xem sai ở chỗ nào ạ? Nếu thuật toán sai thì nó vẫn phải cho ra output chứ.

Ra đầy đấy bạn.

Bạn nên dùng một biến đếm mỗi lần thứ đó xuất hiện thì tăng biến đếm, khi nào biến đếm bằng với số lần thì in ra ngày. Kết thúc lặp mà biến đếm chưa bằng số lần thì in ra không có.

2 Likes

Cái chính là ở đây bác ơi :frowning:
Bằng nhau lần đầu tiên là em cho ra output rồi mà. Cái output em vừa gửi lên là do em thêm lệnh printf 2 số ra thôi.
Không hiểu lý do gì lại không có output trong khi điều kiện của em đã bao quát hết hai trường hợp ( > ) và ( <=) rồi :cry:

Do bạn “bao quát” quá đó.
Bạn viết 2 lệnhi if mà kèm bên trong nữa là break. Bạn thử chạy vòng lặp vào được if ngoài 1 lần xem điều gì xảy ra?
Chắc chắn sẽ vào 1 trong 2 if bên trong. Mà đã vào thì sẽ gặp break, thế là chỉ chạy được 1 lần if ngoài duy nhất là kết thúc luôn.

  • Nếu thằng đó đi xe thì tao bắt nó.
  • Nếu nó không đi xe… tao cũng bắt luôn.

:upside_down_face:

đếm = 0
lặp...
    nếu timthu(...) == k
        đếm = đếm + 1
    nếu đếm == n
        print "Tìm được ngày thứ k lần thứ n của tháng m, năm y là: x/m/y"
        break;

nếu i > tinhngay(...) // Đã lặp hết nhưng không tìm được
    print "Không tìm được."
2 Likes

Cảm ơn bác đã giúp đỡ.
Có vẻ vấn đề ở code của em không phải do những thứ khác mà do printf.
Em thử copy dòng printf này ra hẳn ngoài vòng for mà nó còn không in ra nữa :rofl:
Cảm ơn bác lần nữa <3

Em vẫn chưa hiểu ý này của bác lắm.
Mục đích của em là vào vòng for, lấy ra thứ cần tìm rồi in ra màn hình. Khi đã in ra màn hình kết quả rồi thì đâu cần cho vòng for chạy tiếp hả bác? Nếu cho chạy tiếp nó sẽ in thừa ra màn hình những kết quả sai chứ?
Khi em quote dòng lệnh này để hỏi bác thì mới phát hiện ra nguyên nhân

printf ("%S lan thu %d cua thang %d, nam %d la ngay: %d/%d/%d", input(k), s, m, y, d, m, y);

Chả hiểu sao em lại có thể ghi là %S trong khi đúng ra phải là %s = (((
1 lỗi sai nhỏ nhặt này làm em bồn chồn khó chịu mấy ngày nay :sweat:

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