Member 14520059 Ответов: 3

Почему мой код не работает так, как я думаю?


Я пытаюсь создать конвертер дня в месяц. Точно так же, как если бы я поставил значение равным 1, оно должно показывать 1 января, 32 должно показывать февраль, оно поднимется до 365, а 365 должно показывать 31 декабря.

Но тут есть логическая ошибка. Он хорошо работал только для исходного объекта. Когда я изменил этот объект с помощью префиксного инкремента и назначил его другому. Показанное как присвоенное значение, так и увеличенное значение-это не то, что я ожидаю.

*Примечание:- Я полностью исключаю високосный год.

Что я уже пробовал:

#include<iostream>
#include<string>
using namespace std;

class DayOfYear
{
	private:
		int day;
		string month;
	public:				
		DayOfYear(){}
		DayOfYear(int d){
			day = d;
			month = "";
		}
	
		DayOfYear convert()           
		{
			if(day<=31 ){
				month = "January";	
			}
			else if(day<=59){
				day = day-31;
				month = "February";
			}					
			else if(day<=90){
				day = day-59;
				month = "March";
			}			
			else if(day<=120){
				day = day-90;
				month = "April";
			}			
			else if(day<=151){
				day = day-120;
				month = "May";
			}			
			else if(day<=181){
				day = day-151;
				month = "June";
			}			
			else if(day<=212){
				day = day-181;
				month = "July";
			}			
			else if(day<=243){
				day = day-212;
				month = "August";
			}			
			else if(day<=273){
				day = day-243;
				month = "September";
			}            
			else if(day<=304){
				day = day-273;
				month = "October";
			} 			
			else if(day<=334){
				day = day-304;
				month = "November";
			}			
			else if(day<=365){
				day = day-334;
				month = "December";
			}			
			else if(day==366){
				day = 1;
				month = "January";
			}
			else if(day==0){
				day = 31;
				month = "December";
			}
			else{
				"";
			}
			return 0;
		}
		void print(){
			convert();
			cout<<"mm/dd = "<<month<<" "<<day<<endl;
		}
		
		DayOfYear operator++(){
			DayOfYear d;
			d.day = ++day;
			d.month = month;
			return d;				
		}				
};

int main()
{
	DayOfYear d1(222), d2;
	d1.print();
	d2 = ++d1;
	d1.print();
	d2.print();
}

3 Ответов

Рейтинг:
2

OriginalGriff

Компиляция не означает, что ваш код верен! :смеяться:
Подумайте о процессе разработки как о написании электронного письма: успешная компиляция означает, что вы написали письмо на правильном языке - например, на английском, а не на немецком, - а не то, что письмо содержало сообщение, которое вы хотели отправить.

Итак, теперь вы входите во вторую стадию разработки (на самом деле это четвертая или пятая, но вы перейдете к более ранним стадиям позже): тестирование и отладка.

Начните с рассмотрения того, что он делает, и как это отличается от того, что вы хотели. Это важно, потому что это дает вам информацию о том, почему он это делает. Например, если программа предназначена для того, чтобы позволить пользователю ввести число, а он удваивает его и печатает ответ, то если ввод / вывод был таким:

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16
Тогда совершенно очевидно, что проблема заключается в бите, который удваивает его - он не прибавляет себя к себе или умножает его на 2, он умножает его на себя и возвращает квадрат входного сигнала.
Таким образом, вы можете посмотреть на код, и очевидно, что он находится где-то здесь:
int Double(int value)
   {
   return value * value;
   }

Как только у вас появится идея, что может пойти не так, начните использовать отладчик, чтобы выяснить, почему. Поместите точку останова в первую строку метода и запустите приложение. Когда он достигнет точки останова, отладчик остановится и передаст управление вам. Теперь вы можете запускать свой код построчно (так называемый "одноступенчатый") и просматривать (или даже изменять) содержимое переменных по мере необходимости (черт возьми, вы даже можете изменить код и повторить попытку, если вам это нужно).
Подумайте о том, что должна делать каждая строка кода перед ее выполнением, и сравните это с тем, что она действительно делала, когда вы использовали кнопку "шаг вперед" для выполнения каждой строки по очереди. Он сделал то, что вы ожидали? Если да, то переходите к следующей строке.
Если нет, то почему? Чем это отличается?
Надеюсь, это поможет вам определить, в какой части этого кода есть проблема и в чем она заключается.
Это навык, и его стоит развивать, поскольку он помогает вам как в реальном мире, так и в развитии. И, как и все навыки, он только улучшается при использовании!

Однако я дам вам подсказку: даже если мы проигнорируем високосные годы, сколько дней в феврале?


Member 14520059

Я ценю ваше предложение.. Я буду работать над этим снова должным образом.. И эта дата согласно календарю 2019..So, есть 28 дней в феврале.

Рейтинг:
1

CPallini

Попробуйте (с современным компилятором)

#include <string_view>
#include <iomanip>
#include <iostream>
#include <array>
#include <algorithm>
#include <optional>


class Year
{
  std::array<int, 12> m_days;
  int m_year;

  static std::array <std::string_view, 12> s_month_name;

public:
  Year(int year):m_year(year)
  {
    m_days[0] = 31;
    m_days[1] = m_days[0] + 28;
    if (is_leap() ) ++m_days[1];

    m_days[2] = m_days[1] + 31;
    m_days[3] = m_days[2] + 30;
    m_days[4] = m_days[3] + 31;
    m_days[5] = m_days[4] + 30;
    m_days[6] = m_days[5] + 31;
    m_days[7] = m_days[6] + 31;
    m_days[8] = m_days[7] + 30;
    m_days[9] = m_days[8] + 31;
    m_days[10] = m_days[9] + 30;
    m_days[11] = m_days[10] + 31;
  }

  int year() const {return m_year;}

  std::optional < std::pair < std::string_view, int > > month_and_day(int day) const
  {
    auto it = std::lower_bound( m_days.begin(), m_days.end(), day);
    if ( it == m_days.end() )
      return std::nullopt;

    int offset = it == m_days.begin() ? 0 : *(it-1);
    return make_pair( s_month_name[ it - m_days.begin() ], (day - offset));
  }

  bool is_leap() const
  {
    return ((m_year % 400) == 0) || ((m_year % 4)==0 && (m_year % 100) != 0);
  }
};

using namespace std::literals;
std::array <std::string_view, 12> Year::s_month_name = { "Jan"sv, "Feb"sv, "Mar"sv, "Apr"sv, "May"sv, "Jun"sv, "Jul"sv, "Aug"sv, "Sep"sv, "Oct"sv, "Nov"sv, "Dec"sv};

int main()
{
  std::array<Year,3> year = { 1900, 2000, 2019};

  for ( const auto & y : year)
  {
    for (int d=1; d<=366; ++d)
    {
      auto result = y.month_and_day(d);
      if ( result )
      {
        auto [month, day] = result.value();
        std::cout << std::setw(3) << d << " is " << month << " " << std::setw(2) << day << " " << y.year() << std::endl;
      }
    }
    std::cout << "######################################################################\n";
  }
}


KarstenK

Вы можете рекламировать свое мастерство с помощью: "делай домашнее задание!" ;-)

CPallini

Немного принижает, по моему скромному мнению. :-D
Больше на линии - эй, дорогая, прогуляйся по дикой стороне.". :-D :-D :-D

Рейтинг:
0

KarstenK

Вы не поняли языка для того, что вы хотите сделать. Предоставьте также конструктор по умолчанию с установкой всех значений. (К нулю или к какому-то 1 января)

Операторы должны быть реализованы иначе C++ делает то, что вы, возможно, не захотите. Прочтите это прекрасно учебник по операторам.

Ты пропустил это проблема високосного года совершенно.

совет: я бы работал с именованными константами и сначала проверял високосный год.