例: BMI計算機

スクリーンショット

BMI計算機

プロジェクトレイアウト

bmi_calc/
├── CMakeLists.txt
└── main.cpp

CMakeファイル

CMakeLists.txt:

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(bmi_calc LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(FLTK 1.4 REQUIRED CONFIG)

add_executable(bmi_calc main.cpp)

target_link_libraries(bmi_calc PRIVATE fltk::fltk)

プログラムのソースコード

main.cpp:

#include <FL/Fl.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Window.H>

#include <cerrno>
#include <cstdlib>
#include <limits>
#include <optional>

Fl_Input *height_input_;
Fl_Input *weight_input_;
Fl_Output *result_output_;

std::optional<double> double_value(Fl_Input const *input) {
  char const *value_str = input->value();
  if (*value_str == '\0') {
    return {};  // Empty string is not acceptable
  }

  char *end_str = nullptr;
  errno = 0;

  // NOTE: We can also use std::stod with std::string instead of std::strtod.

  if (double const value = std::strtod(value_str, &end_str);
      *end_str == '\0' && errno == 0) {
    return value;  // Successfully converted to double value
  }
  return {};  // Invalid format
}

void calc_button_cb(Fl_Widget *w, void *data) {
  auto h_cm = double_value(height_input_);
  auto w_kg = double_value(weight_input_);

  if (h_cm.has_value() && w_kg.has_value()) {
    double const h_m = *h_cm / 100;

    // Avoid zero divisions
    if (double const h_m_2 = h_m * h_m;
        h_m_2 > std::numeric_limits<double>::epsilon()) {
      double const bmi = *w_kg / h_m_2;
      result_output_->value(bmi);
      result_output_->textcolor(FL_FOREGROUND_COLOR);
      return;
    }
  }
  result_output_->value("Invalid input.");
  result_output_->textcolor(FL_RED);
}

int main(int argc, char **argv) {
  auto window = new Fl_Window(230, 160, "BMI Calculator");
  height_input_ = new Fl_Input(100, 10, 100, 30, "Height (cm)");
  weight_input_ = new Fl_Input(100, 40, 100, 30, "Weight (kg)");
  auto calc_button = new Fl_Return_Button(20, 80, 180, 30, "Calculate");
  result_output_ = new Fl_Output(100, 120, 100, 30, "BMI");

  calc_button->callback(calc_button_cb);

  window->end();
  window->show(argc, argv);
  return Fl::run();
}

文書の編集
文書の先頭へ