Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.03.2012, 10:41   #1
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию Для заданной даты вычислить дату через заданное число дней

Как лучше оформить функции check и check1
вот код:
Код:
#include <stdio.h>
#include <conio.h>
#include <math.h>
struct Data{
	int day;
	int month;
	int year;
};

void vvod(Data &p) {
	scanf ("%d\n%d\n%d", &p.day, &p.month, &p.year);
}

void vivod(Data &p) {
	printf ("%d\n%d\n%d", p.day,p.month, p.year);
}

//funkciya dlya visokosnogo
void check(int n, int d, int m, int y){
	
	
	
	
	}


}
//fukciya dlya obi4nogo
void check1(int n, int d, int m, int y){



}

int main()
{
	Data d;
	int number;
	vvod(d);
	printf ("Pojalysta vvedite kol-vo dney, kotorie nado pribavlyat`");
	scanf ("%d", &number);
	vivod(d);
	if ((d.year%4==0) & (d.year%100!=0)){// proverka 4to nash year - visokosnyu
		check(number, d.day,d.month, d.year);
	} 
	else
		if ((d.year%4==0) & (d.year%100==0) &	(d.year%400==0)){// proverka 4to nash year - visokosnyu
			check(number, d.day,d.month, d.year);
		}
		else {// proverka 4to nash year - ne visokosnyu
			check1(number, d.day,d.month, d.year);
		}
		getch();
		return 0;
}

Для данной программы надо использовать оператор switch и структуру

Последний раз редактировалось sidestep; 19.03.2012 в 11:01.
sidestep вне форума Ответить с цитированием
Старый 19.03.2012, 12:56   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

я, конечно, совсем не знаю C/C++
но, имхо, проверка на високосность у Вас организована НЕВЕРНО!

по хорошему, она выглядит так (на Паскаль):
Код:
  IsLeapYear := (Year mod 4 = 0)
    and (Year mod 4000 <> 0) and
    ((Year mod 100 <> 0) or (Year mod 400 = 0));
т.е. года, которые кратны 100 не являются високосными, только в том случае, если они не кратны 400.
Ну, чтобы далеко не ходить, возьмите, например, 2000 год. Он был ВИСОКОСНЫМ!

поэтому или добавьте в условие високосности проверку на кратность 400 или выкиньте (совсем!) проверку на кратность 100. (тогда в диапазоне от 1601 года до 2399 года обычная банальная проверка делимости на 4 даёт ответ високосный год или нет).


А вычисление даты через заданное число дней я тут на форуме давал рабочий код, правда, на языке Паскаль. Если сможете перевести на C - то рекомендую воспользоваться поиском..
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.03.2012, 13:21   #3
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

2000 у меня проверяет эта часть
Код:
if ((d.year%4==0) & (d.year%100==0) &	(d.year%400==0))
Не понял в чем ошибка именно у меня
1 условие, если кратен 4 и не кратен 100 - високосный
2 условие, если кратен 100 и кратен 400 - високосный

других вариантов не может быть, или я не прав в чем-то?
пожалуйста тогда пример
sidestep вне форума Ответить с цитированием
Старый 19.03.2012, 13:32   #4
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

так видимо поиском я не умею пользоваться, можно ссылочку, если не трудно?
sidestep вне форума Ответить с цитированием
Старый 19.03.2012, 14:01   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Не понял в чем ошибка именно у меня
для начала то, что я сразу отметил:
Цитата:
Код:
if ((d.year%4==0) & (d.year%100!=0)){// proverka 4to nash year - visokosnyu
тут ПОЧТИ правильно - не учтено деление на 400...

а вот тут:
Цитата:
Код:
if ((d.year%4==0) & (d.year%100==0) &	(d.year%400==0)){// proverka 4to nash year - visokosnyu
уже плохо. если я правильно понимаю синтаксис C, то здесь true будет только, если год делится на 4 И год делится на 100 И год делится на 400... попробуйте, например, 2012 год подставить в данную функцию. Что там у Вас получается? Год високосный получился?!! Или я прав, и ваша конструкция ошибочно выдаст, что это НЕ ВИСОКОСНЫЙ год?!



Цитата:
так видимо поиском я не умею пользоваться, можно ссылочку, если не трудно?
не трудно...
ловите:
Процедура добавления к дате определенного количества дней

Последний раз редактировалось Serge_Bliznykov; 19.03.2012 в 14:06.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.03.2012, 17:01   #6
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

так 2012 делится на 4 и не делится на 100 - поэтому високосный

Написал Ваш код на Си, но выдает неправильный результат
Вот код:

Код:
#include <stdio.h>
#include <conio.h>
#include <math.h>

struct Data{
 int day;
 int month;
 int year;
};


bool isYearIsLeap(int my_year) {
	return (my_year%4 == 0 && my_year%4000 != 0 && (my_year%100 != 0) || (my_year%400 == 0));
}



int getDayinMonth(int my_month, int my_year) {
	int num_days;

	switch (my_month) {
		case 1 :
		case 3 :
		case 5 :
		case 7 :
		case 8 :
		case 10: 
		case 12:
			num_days = 31;
			break;
		case 4 :
		case 6 :
		case 9 :
		case 11:
			num_days = 30;
			break;
		case 2 :
			num_days = 28 + isYearIsLeap(my_year);
			break;
	}
	return num_days;
}

bool validData (Data& my_data) {
	if (my_data.day < 1 || my_data.month > 12) {
		return false;
	} else {
		switch (my_data.month) {
			case 1 :
			case 3 :
			case 5 :
			case 7 :
			case 8 :
			case 10: 
			case 12:
			case 4 :
			case 6 :
			case 9 :
			case 11:
			case 2 :
				return (my_data.day <= getDayinMonth(my_data.month, my_data.year));
				break;
		
		}

	}
}


long long int dateToNumber (Data& my_data) {

	int month = my_data.month, day = my_data.day, year = my_data.year;
	long long int var1, var2, var3;

	if (month > 2) {
		month -= 3;
	} else {
		month += 9;
		year--;
	}
	
	var1 = 146097 * (year/100) / 4;
	var2 = 1461 * (year%100) / 4;
	var3 = (153 * month + 2) / 5 + day + 1721119;

	return var1 + var2 + var3;
} 

Data NumberToDate (long long int my_num, Data& my_data) {
	Data mdata;
	long long int x,y,d,m;

	x = 4 * my_num - 6884477;
	y = (x / 146097) * 100;
	d = (x % 146097) / 4;
	x = 4 * d + 3;
	y = (x / 1461) + y;
	d = (x / 1461) / 4 + 1;
	x = 5 * d - 3;
	m = x / 153 + 1;
	d = (x % 153) / 5 + 1;

	if (m < 11) {
		my_data.month = m + 2;
	} else {
		my_data.month = m - 10;
	}
	my_data.day = d;
	my_data.year = y + m / 11;

	printf ("%d\n%d\n%d\n", my_data.day, my_data.month, my_data.year);
	mdata = my_data;
	return mdata;
}




void vvod(Data& p) {
 scanf ("%d\n%d\n%d", &p.day, &p.month, &p.year);
}

void vivod(Data& p) {
 printf ("%d\n%d\n%d", p.day, p.month, p.year);
}

int main()
{
 Data d, d1;
 int number;
 
 vvod(d);
 
 printf ("\n%d\n%d\n%d", d.day, d.month, d.year);

 
 printf ("\nPojalysta vvedite kol-vo dney, kotorie nado pribavlyat`");
 scanf ("%d", &number);
 
 
 NumberToDate(dateToNumber(d) + number, d1);
 
  printf ("\n%d\n%d\n%d", d1.day, d1.month, d1.year);

 

  getch();
  return 0;
}





У меня всегда выдает месяц под номером 3!
Да я еще не писал функцию на проверку существования даты и не ставил ограничение года
Не могу понять в чем ошибка, существет ли какое-нибудь различиев приоритетах операций си и паскаля? думаю, может в этом ошибка при вычислениях.
sidestep вне форума Ответить с цитированием
Старый 19.03.2012, 17:01   #7
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

вот Ваш код на Паскале:
Код:

{*                    OPDATE.PAS 1.21                    *}
{*     Copyright (c) TurboPower Software 1988, 1992.     *}

function IsLeapYear(Year: Integer): Boolean;
    {-Return True if Year is a leap year}
begin
  IsLeapYear := (Year mod 4 = 0)
    and (Year mod 4000 <> 0) and
    ((Year mod 100 <> 0) or (Year mod 400 = 0));
end;


function DaysInMonth(Month, Year: Integer): Integer;
    {-Return the number of days in the specified month of a given year}
begin
  case Month of
    1, 3, 5, 7, 8, 10, 12:
      DaysInMonth := 31;
    4, 6, 9, 11:
      DaysInMonth := 30;
    2:
      DaysInMonth := 28 + Ord(IsLeapYear(Year));
  else
    DaysInMonth := 0;
  end;
end;

function ValidDate(Day, Month, Year: Integer): Boolean;
    {-Verify that day, month, year is a valid date}
begin

  if (Day < 1) or (Year < 1600) or (Year > 3999) then
    ValidDate := False
  else case Month of
      1..12:
        ValidDate := Day <= DaysInMonth(Month, Year);
    else
      ValidDate := False;
    end
end;


function Date2julian(pDay, pMonth, pYear: integer): longint;
var
  month, day, year: longint;
  ta, tb, tc: longint;
begin
  month := pMonth;
  day := pDay;
  year := pYear;
  if month > 2 then
    month := month - 3
  else
  begin
    month := month + 9;
    year := year - 1;
  end;
  ta := 146097 * (year div 100) div 4;
  tb := 1461 * (year mod 100) div 4;
  tc := (153 * month + 2) div 5 + day + 1721119;
  Date2julian := ta + tb + tc
end;

procedure Julian2date (julian : longint; var pDay, pMonth, pYear : integer);
{Получает значение и возвращает дату в переменные pDay, pMonth, pYear}
var
  x,y,d,m : longint;
begin
  x := 4 * julian - 6884477;
  y := (x div 146097) * 100;
  d := (x MOD 146097) div 4;
  x := 4 * d + 3;
  y := (x div 1461) + y;
  d := (x MOD 1461) div 4 + 1;
  x := 5 * d - 3;
  m := x div 153 + 1;
  d := (x MOD 153) div 5 + 1;
  if m < 11 then
    pMonth := m + 2
  else
    pMonth := m - 10;
  pDay := d;
  pYear := y + m div 11;
end;

var
  a, b, c, q, a1, b1, c1 : integer;
  D1 : Longint;
begin
  WriteLn('Введите дату (три числа: день месяц год) : ');
  Readln(a, b, c);
  if not ValidDate(a, b, c) then begin
    WriteLn('Ошибка! Вы ввели не существующую дату!');
    WriteLn('Bye!');
    Readln;
    Halt(1);
  end;
  WriteLn('Введите количество дней, которое нужно добавить: ');
  Readln(q);

  Julian2date ( Date2julian(a, b, c) + q, a1, b1, c1);


  write('Полученная дата: ',a1,'.',b1,'.',c1);

  Readln;
end.
sidestep вне форума Ответить с цитированием
Старый 19.03.2012, 21:23   #8
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

Короче вот рабочий код:
Код:
#include <stdio.h>
#include <conio.h>
#include <math.h>

struct Data{
	int day;
	int month;
	int year;
};


bool isYearIsLeap(int my_year) {
 //return (my_year%4 == 0 && my_year%4000 != 0 && (my_year%100 != 0) || (my_year%400 == 0));
 if ((my_year%4==0) & (my_year%100!=0)){
  return true;
 } else  if ((my_year%4==0) & (my_year%100==0) & (my_year%400==0)){
  return true;
 }else {
  return false;
 }


}


int getDayinMonth(int my_month, int my_year) {
	int num_days;

	switch (my_month) {
	case 1 :
	case 3 :
	case 5 :
	case 7 :
	case 8 :
	case 10: 
	case 12:
		num_days = 31;
		break;
	case 4 :
	case 6 :
	case 9 :
	case 11:
		num_days = 30;
		break;
	case 2 :
		num_days = 28 + int(isYearIsLeap(my_year));
		break;
	}
	return num_days;
}

bool validData (Data& my_data) {
	if (my_data.day < 1 || my_data.month > 12) {
		return false;
	} else {
		switch (my_data.month) {
		case 1 :
		case 3 :
		case 5 :
		case 7 :
		case 8 :
		case 10: 
		case 12:
		case 4 :
		case 6 :
		case 9 :
		case 11:
		case 2 :
			return (my_data.day <= getDayinMonth(my_data.month, my_data.year));
			break;

		}

	}
}


long int dateToNumber (Data& my_data) {

	int month = my_data.month, day = my_data.day, year = my_data.year;
	long  int var1, var2, var3;

	if (month > 2) {
		month -= 3;
	} else {
		month += 9;
		year--;
	}

	var1 = 146097 * (year/100) / 4;
	var2 = 1461 * (year%100) / 4;
	var3 = (153 * month + 2) / 5 + day + 1721119;

	return var1 + var2 + var3;
} 

Data NumberToDate (long long int my_num, Data& my_data) {
	Data mdata;
	long long int l,j,i,n;

	l = my_num + 68569;
	n = ( 4 * l ) / 146097;
	l = l - ( 146097 * n + 3 ) / 4;
	i = ( 4000 * ( l + 1 ) ) / 1461001;
	l = l - ( 1461 * i ) / 4 + 31;
	j = ( 80 * l ) / 2447;
	my_data.day = l - ( 2447 * j ) / 80;
	l = j / 11;
	my_data.month = j + 2 - ( 12 * l );
	my_data.year = 100 * ( n - 49 ) + i + l;


	printf ("%d\n%d\n%d\n", my_data.day, my_data.month, my_data.year);
	mdata = my_data;
	return mdata;
}


void vvod(Data& p) {
	scanf ("%d\n%d\n%d", &p.day, &p.month, &p.year);
}

void vivod(Data& p) {
	printf ("%d\n%d\n%d", p.day, p.month, p.year);
}

int main()
{
	Data d, d1;
	int number;
	vvod(d);

	if (validData(d) == true) {
		printf ("\n%d\n%d\n%d", d.day, d.month, d.year);
		printf ("\nPojalysta vvedite kol-vo dney, kotorie nado pribavlyat`");
		scanf ("%d", &number);
		printf("\n%i\n", dateToNumber(d));
		NumberToDate(dateToNumber(d) + number, d1);

	} else {
		printf ("vedennaya data nekorektna... ");
	}

	getch();
	return 0;
}
sidestep вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Даны a1,b1,c1, и a2,b2,c2 которые обозначают две даты. Нужно вычислить кол-во дней между этими датами Рафиль Паскаль, Turbo Pascal, PascalABC.NET 6 21.10.2011 10:34
Подсчитать количество дней имея дату Dj_smart Общие вопросы Delphi 7 23.03.2009 12:46
Отредактируйте,пожалуйста,задачу на записи, вычисляющую дату через m дней. JiLiYa Паскаль, Turbo Pascal, PascalABC.NET 2 26.12.2008 09:29
Добавление кол-во дней в дату D@rk M@k Общие вопросы Delphi 1 19.04.2008 10:19
Как сделать отсчет дней от заданной даты в Excel? ru16 Microsoft Office Excel 1 22.11.2007 11:13