Ajutor problema calendar
Last Updated: Dec 23 2017 11:59, Started by
georgecosmin98
, Dec 11 2017 12:55
·
0
#1
Posted 11 December 2017 - 12:55
Buna ziua!
Am o problema care suna asa: .Sa se scrie un program in care se citeste de la tastatura o data calendaristica (zi luna an - citeste 3 val int). Se mai citeste un nr de la tastatura intre 50 si 500. Acest nr reprezinta nr de zile care au trecut de la data x. Sa se afiseza data initiala si data x. Programul merge destul de bine, chiar daca e lucrat destul de neingrijit, dar nu functioneaza cum trebuie cand tastez un an impar. Am reusit sa-mi prind putin urechile si sper sa reusesc sa-i dau de cap. #include <stdio.h> #include <stdlib.h> int zi, luna, an, nr, nr1; int main() { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } while ((luna != 2 && luna % 2 == 0 && zi != 30) || (luna % 2 != 0 && zi != 31) || (luna == 2 && zi != 29 && an % 4 == 0) || (luna == 2 && zi != 28 && an % 4 != 0)) { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } } nr1 = 0; while (nr1 < nr) { nr1++; zi--; if (luna % 2 == 0 && zi == 0 && luna != 2) { luna--; zi = 31; } else if (luna % 2 != 0 && zi == 0 && luna != 1) { luna--; zi = 30; } else if (luna == 1 && zi == 0) { an--; luna = 12; zi = 30; } else if (luna == 2 && zi == 0 && an % 4 == 0) { luna--; zi = 29; } } if (luna == 2 && zi == 0 && an % 4 != 0) { luna--; zi = 28; } printf("\nZi: %d", zi); printf("\nLuna: %d", luna); printf("\nAnul: %d", an); return 0; }
Edited by dani.user, 11 December 2017 - 18:44.
|
#3
Posted 11 December 2017 - 18:32
Lasa anul impar, cum tratezi '29 feb'?
Edited by MarianG, 11 December 2017 - 18:33. |
#4
Posted 11 December 2017 - 21:30
l-am formatat, 29 februarie e cazul cu luna =2 si anul divizibil cu 4 (%4==0)
#include <stdio.h> #include <stdlib.h> int zi, luna, an, nr, nr1; int main() { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } while ((luna != 2 && luna % 2 == 0 && zi != 30) || (luna % 2 != 0 && zi != 31) || (luna == 2 && zi != 29 && an % 4 == 0) || (luna == 2 && zi != 28 && an % 4 != 0)) { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } } nr1 = 0; while (nr1 < nr) { nr1++; zi--; if (luna % 2 == 0 && zi == 0 && luna != 2) { luna--; zi = 31; } else if (luna % 2 != 0 && zi == 0 && luna != 1) { luna--; zi = 30; } else if (luna == 1 && zi == 0) { an--; luna = 12; zi = 30; } else if (luna == 2 && zi == 0 && an % 4 == 0) { luna--; zi = 29; } } if (luna == 2 && zi == 0 && an % 4 != 0) { luna--; zi = 28; } printf("\nZi: %d", zi); printf("\nLuna: %d", luna); printf("\nAnul: %d", an); return 0; } Edited by georgecosmin98, 11 December 2017 - 21:31. |
#5
Posted 11 December 2017 - 23:08
se da un sir cu 12 elemente, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - 28 sau 29 in functie de an.
iti alegi o data de plecare, si un interval de mers din intervalul de mers, scazi numarul de zile ramese din fiecare luna .. vezi in ce luna ajugi Edited by MarianG, 11 December 2017 - 23:09. |
#6
Posted 12 December 2017 - 12:26
Pai cam asta am facut in programul de mai jos. Singura problema e cand introduc un an impar si un nr de zile trecute de la data x > 317. (in codul de mai sus aveam o eroare in while-ul al 4-lea
#include <stdio.h> #include <stdlib.h> int zi, luna, an, nr, nr1; int main() { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } while ((luna != 2 && luna % 2 == 0 && zi > 30) || (luna % 2 != 0 && zi < 31) || (luna == 2 && zi > 29 && an % 4 == 0) || (luna == 2 && zi > 28 && an % 4 != 0)) { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); } while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } nr1 = 0; while (nr1 < nr) { nr1++; zi--; if (luna % 2 == 0 && zi == 0 && luna != 2) { luna--; zi = 31; } else if (luna % 2 != 0 && zi == 0 && luna != 1) { luna--; zi = 30; } else if (luna == 1 && zi == 0) { an--; luna = 12; zi = 30; } else if (luna == 2 && zi == 0 && an % 4 == 0) { luna--; zi = 29; } } if (luna == 2 && zi == 0 && an % 4 != 0) { luna--; zi = 28; } printf("\nZi: %d", zi); printf("\nLuna: %d", luna); printf("\nAnul: %d", an); return 0; } Edited by georgecosmin98, 12 December 2017 - 12:27. |
#7
Posted 12 December 2017 - 20:09
Arata-mi doar bucata de cod unde ai sirul respectiv cu valorile pentru fiecare luna.
printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an);Conform programului tau exista 31 Februarie Edited by MarianG, 12 December 2017 - 20:10. |
#8
Posted 12 December 2017 - 20:15
Mai jos e bucata de cod de care vorbesc. pur si simplu cresc nr1 pana cand ajunge egal cu nr(numarul de zile trecute de la data x) si scad ziua, apoi luna si daca e cazul anul.
nr1=0; while (nr1<nr) {nr1++; zi--; if (luna%2==0&&zi==0&&luna!=2) {luna--; zi=31;} else if(luna%2!=0&&zi==0&&luna!=1) {luna--; zi=30;} else if(luna==1&&zi==0) {an--; luna=12; zi=30;} else if (luna==2&&zi==0&&an%4==0) {luna--; zi=29;} else if (luna==2&&zi==0&&an%4!=0) {luna--; zi=28;}} Nu exista 31 februarie pentru ca am un while putin mai jos while ((luna != 2 && luna % 2 == 0 && zi > 30) || (luna % 2 != 0 && zi < 31) || (luna == 2 && zi > 29 && an % 4 == 0) || (luna == 2 && zi > 28 && an % 4 != 0)) |
#9
Posted 12 December 2017 - 20:27
if ( zi <= calendar[luna] ) // adica sa verifici daca ziua introdusa este in luna respectiva //
n-ar fi mai simplu? // citesti an // lungesti februarie la 29 de zile daca este cazul // citesti o luna // citest o zi Edited by MarianG, 12 December 2017 - 20:27. |
#10
Posted 12 December 2017 - 20:31
Ba cred ca da, dar ce am facut eu mai sus a fost prima varianta care mi-a venit in minte si sa fiu sincer nici nu mi-am batut capul prea mult cu citirea. Mai ales ca am vazut ca ruleaza bine din prima (prima incercare a fost cu an par). Dar dupa ce am testat mai mult programul mi-am dat seama ca daca anul e impar si numarul de zile trecute de la data x >317 imi afiseza pe - zilelel
Aparent aveam o greseala in while-ul de mai jos while ((luna != 2 && luna % 2 == 0 && zi > 30) || (luna % 2 != 0 && zi < 31) || (luna == 2 && zi > 29 && an % 4 == 0) || (luna == 2 && zi > 28 && an % 4 != 0)) si anume, a doua paranteza ma baga in while daca zi <31 ceea ce e gresit deoarece trebuia sa ma bage in while cand zi>31 (neatentia). Acum aparent merge ok programul si nu am mai reusit sa refac problema sa-mi afiseze cu - la zi. Debugul e Sfant, problema e ca inca sunt in stadiul in care invat sa il folosesc. Programul final o sa-l mai testez(l-am lasat mai jos poate mai are cineva nevoie) si daca gasesc vreo greseala sau o problema de afisare o sa revin #include <stdio.h> #include <stdlib.h> int zi, luna, an, nr, nr1; int main() { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } while ((luna != 2 && luna % 2 == 0 && zi > 30) || (luna % 2 != 0 && zi > 31) || (luna == 2 && zi > 29 && an % 4 == 0) || (luna == 2 && zi > 28 && an % 4 != 0)) { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); } while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } nr1 = 0; while (nr1 < nr) { nr1++; zi--; if (luna % 2 == 0 && zi == 0 && luna != 2) { luna--; zi = 31; } else if (luna % 2 != 0 && zi == 0 && luna != 1) { luna--; zi = 30; } else if (luna == 1 && zi == 0) { an--; luna = 12; zi = 30; } else if (luna == 2 && zi == 0 && an % 4 == 0) { luna--; zi = 29; } else if (luna == 2 && zi == 0 && an % 4 != 0) { luna--; zi = 28; } } printf("\nZi: %d", zi); printf("\nLuna: %d", luna); printf("\nAnul: %d", an); return 0; } Edited by georgecosmin98, 12 December 2017 - 20:43. |
|
#11
Posted 22 December 2017 - 13:16
Problema de mai sus e gresita, am stat, am analizat si am incercat sa o depanez. Pur si simplu sunt doua variante (cred). Ori sunt prea prost ori prea idiot..... . In mintea mea lunile impare aveau 31 de zile, lunile pare 30 si luna februarie 28/29 (in functie de an), un detaliu care pare mic, dar care mi-a mancat cateva ore bune. @MarianG mi-a spus in postul #5 acest lucru, dar din graba, oboseala sau prostie nu m-am prins si am citit ceva de genul (31,28/29,31,30,31....).
Am reusit sa fac problema si sper ca acum e ok. Las mai jos codul poate mai are cineva nevoie de el, sau poate se mai observa ceva errori pe care eu poate le-am ratat. #include <stdio.h> #include <stdlib.h> int zi, luna, an, nr, nr1, v[5] = {31, 30, 29, 28}; int main() { printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } while ((luna != 2 && luna % 2 == 0 && zi > 30) || (luna % 2 != 0 && zi > 31) || (luna == 2 && zi > 29 && an % 4 == 0) || (luna == 2 && zi > 28 && an % 4 != 0)) { printf("Te rog sa introduci o data valida\n"); printf("Introduceti ziua: "); scanf("%d", &zi); while (zi < 1 || zi > 31) { printf("\nIntroduceti o valoare intre 1 si 31\n"); scanf("%d", &zi); } printf("\nIntroduceti luna: "); scanf("%d", &luna); while ((luna < 1 || luna > 12)) { printf("\nIntroduceti o valoare intre 1 si 12\n"); scanf("%d", &luna); } printf("\nIntroduceti anul: "); scanf("%d", &an); printf("Introduceti numarul de zile care au trecut de la data x: "); scanf("%d", &nr); } while (nr < 50 || nr > 500) { printf("\nIntroduceti o valoare intre 50 si 500\n"); scanf("%d", &nr); } nr1 = 0; while (nr1 < nr) { printf("nr=%d , zi=%d , luna =%d \n", nr1, zi, luna); nr1++; zi--; // printf("nr=%d , zi=%d , luna =%d \n",nr1,zi,luna); if ((luna == 5 && zi == 0) || (luna == 7 && zi == 0) || (luna == 10 && zi == 0) || (luna == 12 && zi == 0)) { luna--; zi = v[1]; } else if ((luna == 2 && zi == 0) || (luna == 4 && zi == 0) || (luna == 6 && zi == 0) || (luna == 9 && zi == 0) || (luna == 11 && zi == 0) || (luna == 8 && zi == 0)) { luna--; zi = v[0]; } else if (luna == 3 && zi == 0 && an % 4 == 0) { luna--; zi = v[2]; } else if (luna == 3 && zi == 0 && an % 4 != 0) { luna--; zi = v[3]; } if (luna == 1 && zi == 0) { an--; luna = 12; zi = v[0]; } } printf("\nZi: %d", zi); printf("\nLuna: %d", luna); printf("\nAnul: %d", an); return 0; } |
#12
Posted 22 December 2017 - 16:48
De ce repeti aproape tot codul de la inceput cateva randuri mai jos?
As inlocui toate acele if-uri cu un tablou cu numarul de zile ale unui an. #include <stdio.h> struct DataCalendaristica { int an; int luna; int zi; }; int cateZileAreLuna(int luna, int an) { static const int numarZileAleLunii[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; static const int numarLuni = 12; luna -= 1;//indexam de la 0 if (luna < 0 || luna > numarLuni) return 0; int rezultat = numarZileAleLunii[luna]; if (luna == 1 && ((an % 4) == 0)) { rezultat += 1; } return rezultat; } void adaugaZile(struct DataCalendaristica* data, unsigned int numarZile) { while (numarZile > 0) { int numarZileLunaCurenta = cateZileAreLuna(data->luna, data->an); if (data->zi == numarZileLunaCurenta) { //sfarsit de luna, avansam cu o zi numarZile -= 1; data->luna += 1; data->zi = 1; } else { int zileDeAdaugatLunaAceasta = numarZileLunaCurenta - data->zi; if (zileDeAdaugatLunaAceasta > numarZile) { zileDeAdaugatLunaAceasta = numarZile; } data->zi += zileDeAdaugatLunaAceasta; numarZile -= zileDeAdaugatLunaAceasta; } if (data->luna == 13) { data->luna = 1; data->an += 1; } } } int main(void) { struct DataCalendaristica data = { 2000, 01, 15 }; printf("Inainte: %d-%d-%d\n", data.an, data.luna, data.zi); adaugaZile(&data, 75); printf("Dupa 75 de zile: %d-%d-%d\n", data.an, data.luna, data.zi); } |
#13
Posted 22 December 2017 - 18:29
O mică precizare: în calendarul gregorian, un an bisect este divizibil cu 4, sau cu 400, dar nu cu 100.
Presupun că a fost folosită doar condiția de divizibilitate cu 4 pentru simplificarea codului. |
#14
Posted 22 December 2017 - 18:32
Clar, pentru cod de rulat in aplicatii reale exista biblioteci ce si-au batut capul cu toate nuantele calendarelor.
|
#15
Posted 23 December 2017 - 11:59
Am repetat codul pentru a putea verifica daca data introdusa este valida, iar in caz de invaliditate afisam mesajul "Te rog sa introduci o data valida" si reciteam o data, pe care o reverificam. Asa am gandit programul la inceput, sunt sigur ca exista multe variante mult mai simple ale programului (una este mai sus, varianta lui @dani.user). La inceput am vrut sa fac tot cu structuri, dar mi s-a parut mai usor fara.
Multumesc frumos tuturor pentru ajutor si va doresc sarbatori fericite tuturor! |
|
Anunturi
Bun venit pe Forumul Softpedia!
▶ 0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users